CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Running, Solving & CFD

Updating Boundary Conditions Each Iteration

Register Blogs Community New Posts Updated Threads Search

Like Tree53Likes

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   May 25, 2011, 09:24
Default Updating Boundary Conditions Each Iteration
  #1
New Member
 
Tom Witten
Join Date: May 2011
Location: Freiberg
Posts: 10
Rep Power: 15
thomas99 is on a distinguished road
Hello All,

I have a situation where I would like to calculate some boundary conditions from the internal field. The problem is that, for each time step, the boundary conditions should be iteratively updated as part of the solution. I have searched the forum and noticed that many people have recommended the groovyBC or swak4Foam add ons for recalculating a boundary condition from the flow field but these tools seem to do this at the end of a time step and not as part of the iterative process. Can I use one of these tools to somehow calculate the BCs iteratively?

Alternatively, I noticed there is a BC built into openFoam called calculated that might work but I can't really find too much information about this in the forum and the tutorials don't really make it clear to me exactly how it works.

Does anyone have any idea how I can iteratively calculate boundary conditions?

Regards,
Tom
thomas99 is offline   Reply With Quote

Old   May 25, 2011, 10:02
Default
  #2
Senior Member
 
David Gaden
Join Date: Apr 2009
Location: Winnipeg, Canada
Posts: 437
Rep Power: 22
marupio is on a distinguished road
I don't think groovyBC does iterative solutions. You may need to write your own boundary condition, and put the iterative solver into it. See

http://openfoamwiki.net/index.php/Ho...dary_condition

for an overview of writing new boundary conditions.
Zhiheng Wang likes this.
marupio is offline   Reply With Quote

Old   May 25, 2011, 10:31
Default
  #3
New Member
 
Tom Witten
Join Date: May 2011
Location: Freiberg
Posts: 10
Rep Power: 15
thomas99 is on a distinguished road
Hi Marupio,

Thanks for the reply and the link.

I was hoping that I wouldn't have to do that but I'll give it a try.

Best,
Tom
thomas99 is offline   Reply With Quote

Old   May 25, 2011, 10:35
Default
  #4
Super Moderator
 
bigphil's Avatar
 
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,097
Rep Power: 34
bigphil will become famous soon enoughbigphil will become famous soon enough
Hi thomas99,

As marupio said you could write your own boundary condition,

alternatively, you could just include a header file which updates the boundary contact inside your solver solution loop,
for example I sometimes use the "fixedGradient" boundary condition in my solid stress solver to apply a traction, this means I must update this fixedGradient every solution iteration.
The header file might look something like the following (where U is the volVectorField I solve for):
Code:
label patchID = mesh.boundaryMesh().findPatchID("patch_of_interest_name");
if
(
  U.boundaryField()[patchID].type()
   == fixedGradientFvPatchVectorField::typeName
)
{
          fixedGradientFvPatchVectorField& Upatch =
	    refCast<fixedGradientFvPatchVectorField>(U.boundaryField()[patchID]);
	  
	  Upatch.gradient() = (.......calculate something here.....);
}

Hope it helps,
Philip
bigphil is offline   Reply With Quote

Old   May 25, 2011, 11:03
Default
  #5
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by thomas99 View Post
Hello All,

I have a situation where I would like to calculate some boundary conditions from the internal field. The problem is that, for each time step, the boundary conditions should be iteratively updated as part of the solution. I have searched the forum and noticed that many people have recommended the groovyBC or swak4Foam add ons for recalculating a boundary condition from the flow field but these tools seem to do this at the end of a time step and not as part of the iterative process. Can I use one of these tools to somehow calculate the BCs iteratively?
Depends on what you mean by iterative. groovyBC is recalculated every time other BCs are recalculated too (sol also in a loop inside the time-loop)

Quote:
Originally Posted by thomas99 View Post
Alternatively, I noticed there is a BC built into openFoam called calculated that might work but I can't really find too much information about this in the forum and the tutorials don't really make it clear to me exactly how it works.
Forget this one. It means "I was calculated once, I won't change again. And I don't know if I'm Dirichlet or Neuman so I will behave like a Dirichlet"
Zhiheng Wang likes this.
gschaider is offline   Reply With Quote

Old   May 26, 2011, 05:20
Default
  #6
New Member
 
Tom Witten
Join Date: May 2011
Location: Freiberg
Posts: 10
Rep Power: 15
thomas99 is on a distinguished road
Hi Philip and Bernhard,

Thanks for the information. I think the inclusion of a header file is a good idea and I'll try that first.

Regards,
Tom
Zhiheng Wang likes this.
thomas99 is offline   Reply With Quote

Old   August 29, 2012, 13:21
Default
  #7
New Member
 
Wei Liu
Join Date: Apr 2011
Location: West Lafayette, IN
Posts: 29
Rep Power: 15
mathslw is on a distinguished road
Quote:
Originally Posted by thomas99 View Post
Hi Philip and Bernhard,

Thanks for the information. I think the inclusion of a header file is a good idea and I'll try that first.

Regards,
Tom
Hi Tom,

Do you succeed in updating the boundary in the loop?
I want to update the boundary condition after each iteration for steady state calculation.
Thanks!

Wei
mathslw is offline   Reply With Quote

Old   August 29, 2012, 13:26
Default
  #8
Senior Member
 
David Gaden
Join Date: Apr 2009
Location: Winnipeg, Canada
Posts: 437
Rep Power: 22
marupio is on a distinguished road
I'm not infront of my FOAM machine right now, but I seem to recall an issue where the boundary condition would update only once per timestep. I was doing multiple iterations per timestep, and I had to call some function to force it to update. I forget the details... but if you encounter the situation where it only seems to update once, then let me know, I'll dig for the answer.

-Dave
__________________
~~~
Follow me on twitter @DavidGaden
marupio is offline   Reply With Quote

Old   August 29, 2012, 13:30
Default
  #9
New Member
 
Wei Liu
Join Date: Apr 2011
Location: West Lafayette, IN
Posts: 29
Rep Power: 15
mathslw is on a distinguished road
Quote:
Originally Posted by marupio View Post
I'm not infront of my FOAM machine right now, but I seem to recall an issue where the boundary condition would update only once per timestep. I was doing multiple iterations per timestep, and I had to call some function to force it to update. I forget the details... but if you encounter the situation where it only seems to update once, then let me know, I'll dig for the answer.

-Dave
Hi Dave,

I am using the steady state solver, so I want to update the valure after each iteration.
Do you know about that?

Thanks!

Wei
mathslw is offline   Reply With Quote

Old   August 29, 2012, 14:08
Default
  #10
New Member
 
Wei Liu
Join Date: Apr 2011
Location: West Lafayette, IN
Posts: 29
Rep Power: 15
mathslw is on a distinguished road
Quote:
Originally Posted by bigphil View Post
Hi thomas99,

As marupio said you could write your own boundary condition,

alternatively, you could just include a header file which updates the boundary contact inside your solver solution loop,
for example I sometimes use the "fixedGradient" boundary condition in my solid stress solver to apply a traction, this means I must update this fixedGradient every solution iteration.
The header file might look something like the following (where U is the volVectorField I solve for):
Code:
label patchID = mesh.boundaryMesh().findPatchID("patch_of_interest_name");
if
(
  U.boundaryField()[patchID].type()
   == fixedGradientFvPatchVectorField::typeName
)
{
          fixedGradientFvPatchVectorField& Upatch =
	    refCast<fixedGradientFvPatchVectorField>(U.boundaryField()[patchID]);
	  
	  Upatch.gradient() = (.......calculate something here.....);
}

Hope it helps,
Philip
Hi Philip,

What should I do if I used the fixedValue and want to update it?
Thanks!

Wei
Zhiheng Wang and TeddyL like this.
mathslw is offline   Reply With Quote

Old   August 29, 2012, 14:29
Default
  #11
Super Moderator
 
bigphil's Avatar
 
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,097
Rep Power: 34
bigphil will become famous soon enoughbigphil will become famous soon enough
Quote:
Originally Posted by mathslw View Post
What should I do if I used the fixedValue and want to update it?
Thanks!
Hi Wei,

For a fixedValue boundary condition, you can do the following (U is the volVectorField which is solved):
Code:
// find ID of patch
label patchID = mesh.boundaryMesh().findPatchID("patch_of_interest");
// check patch has been found
if(patchID == -1)
{
  FatalError << "patch not found!" << exit(FatalError);
}

// set value on patch to what ever you want
U.boundaryField()[patchID] == vector(1,2,3);
Note the double equal signs, this is how you set the value on a patch. You don't need to cast the patch if it is fixedValue.

Hope it helps,
Philip
fs82, EhsanMh, meth and 3 others like this.
bigphil is offline   Reply With Quote

Old   August 29, 2012, 15:01
Default
  #12
New Member
 
Wei Liu
Join Date: Apr 2011
Location: West Lafayette, IN
Posts: 29
Rep Power: 15
mathslw is on a distinguished road
Quote:
Originally Posted by bigphil View Post
Hi Wei,

For a fixedValue boundary condition, you can do the following (U is the volVectorField which is solved):
Code:
// find ID of patch
label patchID = mesh.boundaryMesh().findPatchID("patch_of_interest");
// check patch has been found
if(patchID == -1)
{
  FatalError << "patch not found!" << exit(FatalError);
}
 
// set value on patch to what ever you want
U.boundaryField()[patchID] == vector(1,2,3);
Note the double equal signs, this is how you set the value on a patch. You don't need to cast the patch if it is fixedValue.

Hope it helps,
Philip
Hi Philip,

Your suggestion is very helpful!

If I use U.boundaryField()[patchID] == vector(1,2,3) , the boundary would be uniform.
Can I use a loop to set non-uniform boundary conditions?
Besides, to set the new boundary, I have to make use of the velocity on the boundary face, velocity on the boundary cell and velocity gradient on the boundary cell. Do you know how to access these values?

Many thanks!

Wei
meth and Zhiheng Wang like this.
mathslw is offline   Reply With Quote

Old   August 30, 2012, 09:50
Default
  #13
Super Moderator
 
bigphil's Avatar
 
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,097
Rep Power: 34
bigphil will become famous soon enoughbigphil will become famous soon enough
Hi Wei,

You can set non-uniform boundary values based on anything you want:
Code:
// find ID of patch
label patchID = mesh.boundaryMesh().findPatchID("patch_of_interest");
// check patch has been found
if(patchID == -1)
{
  FatalError << "patch not found!" << exit(FatalError);
}
 
// set value on patch
forAll(U.boundaryField()[patchID], facei)
{
   vector faceOldVel = U.boundaryField()[patchID][facei];
   vector faceCellOldVel =
         U.internalField()[mesh.boundaryMesh()[patchID].faceCells()[facei]];
   vector faceSnGrad = U.boundaryField()[patchID].snGrad()[facei];
   
   // set whatever you want here 
   U.boundaryField()[patchID][facei] == faceOldVel + faceCellOldVel + faceSnGrad;
}
Best regards,
Philip
bigphil is offline   Reply With Quote

Old   August 30, 2012, 13:01
Default
  #14
New Member
 
Wei Liu
Join Date: Apr 2011
Location: West Lafayette, IN
Posts: 29
Rep Power: 15
mathslw is on a distinguished road
Quote:
Originally Posted by bigphil View Post
Hi Wei,

You can set non-uniform boundary values based on anything you want:
Code:
// find ID of patch
label patchID = mesh.boundaryMesh().findPatchID("patch_of_interest");
// check patch has been found
if(patchID == -1)
{
  FatalError << "patch not found!" << exit(FatalError);
}
 
// set value on patch
forAll(U.boundaryField()[patchID], facei)
{
   vector faceOldVel = U.boundaryField()[patchID][facei];
   vector faceCellOldVel =
         U.internalField()[mesh.boundaryMesh()[patchID].faceCells()[facei]];
   vector faceSnGrad = U.boundaryField()[patchID].snGrad()[facei];
 
   // set whatever you want here 
   U.boundaryField()[patchID][facei] == faceOldVel + faceCellOldVel + faceSnGrad;
}
Best regards,
Philip
Hi Philip,

Thanks for your reply!
I will try it in my program to see how it is works!

Best Regards!

Wei
Zhiheng Wang likes this.
mathslw is offline   Reply With Quote

Old   August 30, 2012, 13:13
Default
  #15
New Member
 
Wei Liu
Join Date: Apr 2011
Location: West Lafayette, IN
Posts: 29
Rep Power: 15
mathslw is on a distinguished road
Quote:
Originally Posted by bigphil View Post
Hi Wei,

You can set non-uniform boundary values based on anything you want:
Code:
// find ID of patch
label patchID = mesh.boundaryMesh().findPatchID("patch_of_interest");
// check patch has been found
if(patchID == -1)
{
  FatalError << "patch not found!" << exit(FatalError);
}
 
// set value on patch
forAll(U.boundaryField()[patchID], facei)
{
   vector faceOldVel = U.boundaryField()[patchID][facei];
   vector faceCellOldVel =
         U.internalField()[mesh.boundaryMesh()[patchID].faceCells()[facei]];
   vector faceSnGrad = U.boundaryField()[patchID].snGrad()[facei];
 
   // set whatever you want here 
   U.boundaryField()[patchID][facei] == faceOldVel + faceCellOldVel + faceSnGrad;
}
Best regards,
Philip
Hi Philip,

As far as I know, the U.boundaryField()[patchID].snGrad()[facei] returns the patch-normal gradient. How to obtain the velocity gradient on the patch cell, which is a tensor. Can I define a
tensorField gradU = fvc::grad(U),
then use the
tensor faceCellGradientU =
gradU.internalField()[mesh.boundaryMesh()[patchID].faceCells()[facei]];
to obtain the velocity gradient on the patch cell?

Many thanks!

Wei
Zhiheng Wang likes this.
mathslw is offline   Reply With Quote

Old   September 9, 2012, 18:19
Default
  #16
New Member
 
Wei Liu
Join Date: Apr 2011
Location: West Lafayette, IN
Posts: 29
Rep Power: 15
mathslw is on a distinguished road
Quote:
Originally Posted by bigphil View Post
Hi Wei,

You can set non-uniform boundary values based on anything you want:
Code:
// find ID of patch
label patchID = mesh.boundaryMesh().findPatchID("patch_of_interest");
// check patch has been found
if(patchID == -1)
{
  FatalError << "patch not found!" << exit(FatalError);
}
 
// set value on patch
forAll(U.boundaryField()[patchID], facei)
{
   vector faceOldVel = U.boundaryField()[patchID][facei];
   vector faceCellOldVel =
         U.internalField()[mesh.boundaryMesh()[patchID].faceCells()[facei]];
   vector faceSnGrad = U.boundaryField()[patchID].snGrad()[facei];
 
   // set whatever you want here 
   U.boundaryField()[patchID][facei] == faceOldVel + faceCellOldVel + faceSnGrad;
}
Best regards,
Philip
Hi Philip,

Sorry to bother u again.
If I use

U.boundaryField()[patchID] == vector(0.8, 0, 0);

I could update the boundary condition;
But if I use

forAll(U.boundaryField()[patchID],i)
{
U.boundaryField()[patchID][i] == vector(0.8, 0, 0);
}

The boundary would not be updated.

Do you know the reason?

Thanks!

Wei
Zhiheng Wang and jennyjian like this.
mathslw is offline   Reply With Quote

Old   September 10, 2012, 11:03
Default
  #17
Super Moderator
 
bigphil's Avatar
 
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,097
Rep Power: 34
bigphil will become famous soon enoughbigphil will become famous soon enough
Hi Wei,

To answer your first question, to calculate the full gradient (tensor) at the boundary face you use the fvc::grad operator as you have shown:
tensor faceCellGradientU =
gradU.internalField()[mesh.boundaryMesh()[patchID].faceCells()[facei]];

However, be careful because most fvc::grad schemes do not calculate the total gradient fully at boundary faces, they essentially calculate the normal gradient like snGrad and then they set the tangential gradient to be the same as the tangential gradient at the centre of the boundary cell.

As regards the forAll loop not updating the boundary I am not sure but here is a work-around:
Code:
vectorField newPatchValues(U.boundaryField()[patchID].size(), vector::zero);

forAll(U.boundaryField()[patchID],i)
{
    newPatchValues[i] = vector(0.8, 0, 0);
 }

U.boundaryField()[patchID][i] == newPatchValues;
Also, did you try chaining the "==" to "=" inside the forAll loop?
Zhiheng Wang and albet like this.
bigphil is offline   Reply With Quote

Old   September 10, 2012, 14:07
Default
  #18
New Member
 
Wei Liu
Join Date: Apr 2011
Location: West Lafayette, IN
Posts: 29
Rep Power: 15
mathslw is on a distinguished road
Quote:
Originally Posted by bigphil View Post
Hi Wei,

To answer your first question, to calculate the full gradient (tensor) at the boundary face you use the fvc::grad operator as you have shown:
tensor faceCellGradientU =
gradU.internalField()[mesh.boundaryMesh()[patchID].faceCells()[facei]];

However, be careful because most fvc::grad schemes do not calculate the total gradient fully at boundary faces, they essentially calculate the normal gradient like snGrad and then they set the tangential gradient to be the same as the tangential gradient at the centre of the boundary cell.

As regards the forAll loop not updating the boundary I am not sure but here is a work-around:
Code:
vectorField newPatchValues(U.boundaryField()[patchID].size(), vector::zero);
 
forAll(U.boundaryField()[patchID],i)
{
    newPatchValues[i] = vector(0.8, 0, 0);
 }
 
U.boundaryField()[patchID][i] == newPatchValues;
Also, did you try chaining the "==" to "=" inside the forAll loop?
Hi Philip,

You are right, I tried to change the "==" to "=" inside the forAll loop and it works.
In your code, you write "U.boundaryField()[patchID][i] == newPatchValues", is it U.boundaryField()[patchID]== newPatchValues? without the [i]?

Many thanks!

Wei
Zhiheng Wang likes this.
mathslw is offline   Reply With Quote

Old   September 10, 2012, 15:17
Default
  #19
Super Moderator
 
bigphil's Avatar
 
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,097
Rep Power: 34
bigphil will become famous soon enoughbigphil will become famous soon enough
Quote:
Originally Posted by mathslw View Post
In your code, you write "U.boundaryField()[patchID][i] == newPatchValues", is it U.boundaryField()[patchID]== newPatchValues? without the [i]?
Yes, sorry that was a typo.

Best regards,
Philip
bigphil is offline   Reply With Quote

Old   June 26, 2015, 18:49
Default
  #20
Senior Member
 
Alejandro
Join Date: Jan 2014
Location: Argentina
Posts: 128
Rep Power: 12
ancolli is on a distinguished road
Quote:
Originally Posted by bigphil View Post
Hi Wei,

You can set non-uniform boundary values based on anything you want:
Code:
// find ID of patch
label patchID = mesh.boundaryMesh().findPatchID("patch_of_interest");
// check patch has been found
if(patchID == -1)
{
  FatalError << "patch not found!" << exit(FatalError);
}
 
// set value on patch
forAll(U.boundaryField()[patchID], facei)
{
   vector faceOldVel = U.boundaryField()[patchID][facei];
   vector faceCellOldVel =
         U.internalField()[mesh.boundaryMesh()[patchID].faceCells()[facei]];
   vector faceSnGrad = U.boundaryField()[patchID].snGrad()[facei];
   
   // set whatever you want here 
   U.boundaryField()[patchID][facei] == faceOldVel + faceCellOldVel + faceSnGrad;
}
Best regards,
Philip

I have the following error when i try to compile the code for a scalar T:

DCP.C: In function ‘int main(int, char**)’:
DCP.C:75:66: error: no match for ‘operator[]’ (operand types are ‘Foam::tmp<Foam::Field<double> >’ and ‘Foam::label {aka int}’)
newPatchValues[i] = -T.boundaryField()[patchID].snGrad()[i];
^
make: *** [Make/linux64GccDPOpt/DCP.o] Error 1


any idea?
Zhiheng Wang likes this.
ancolli is offline   Reply With Quote

Reply


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 Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Impinging Jet Boundary Conditions Anindya Main CFD Forum 25 February 27, 2016 13:58
OpenFOAM Variable Velocity Boundary Conditions NickolasPl OpenFOAM Programming & Development 2 May 19, 2011 06:37
Concentric tube heat exchanger (Air-Water) Young CFX 5 October 7, 2008 00:17
[Commercial meshers] Trimmed cell and embedded refinement mesh conversion issues michele OpenFOAM Meshing & Mesh Conversion 2 July 15, 2005 05:15
A problem about setting boundary conditions lyang Main CFD Forum 0 September 19, 1999 19:29


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