CFD Online Discussion Forums

CFD Online Discussion Forums (
-   OpenFOAM Running, Solving & CFD (
-   -   Adding a field on patch in parallel (

jaswi January 31, 2008 12:22

Dear Forum Wish you all a
Dear Forum

Wish you all a very nice day.

I am summing faces area of a patch depending upon a criteria and the code is :

label patchID = mesh.boundaryMesh().findPatchID("cylinder");
const polyPatch& cPatch = mesh.boundaryMesh()[patchID];
const surfaceScalarField& magSf = mesh.magSf();

scalar patchAreaTemp=0.0;

forAll(cPatch, facei)

if(gamma.boundaryField()[patchID][facei] > 0.0)
patchAreaTemp += magSf.boundaryField()[patchID][facei];

This works fine when used on a single processor. When I divide my patch across processors and use the same code, I get the wrong value.

Could anybody please suggest how to do it correctly in parallel

Thanks in advance

With Kind Regards

philippose January 31, 2008 14:11

Hi Jaswinder, A Good evenin
Hi Jaswinder,

A Good evening to you too :-)!

So... lets see if we can use some of OpenFOAM's numerous helper functions to solve your problem :-)!

I suggest you try replacing all that code you have starting from the "forAll" right to the last bracket with the following single line of code:

patchAreaTemp = gSum(notEqual(gamma.boundaryField()[patchID],0.0) * pos(gamma.boundaryField()[patchID]) * magSf.boundaryField()[patchID]);

This should work :-)!

A short explanation:

"gSum" is gather sum, and far as I have seen, it automatically collects all the data across a parallel simulation, and sums it up.

"notEqual" as the name implies... checks if the gamma value is equal to zero or not... if the value is equal to zero, the function gives a "0" else it gives a "1"

"pos" checks if your gamma value is a positive number or not... if value >= 0, the function returns "1", else "0"

So if you put them all together, you should get what you need.

Let me know what happens :-)!

Have a nice evening!


jaswi January 31, 2008 14:27

Hi Philippose Thanks for th
Hi Philippose

Thanks for the quick reply.

That indeed is some smart FOAMing.

I tried it but i am getting error for the notEqual() functionality.

The code snippet now reads :

label patchID = mesh.boundaryMesh().findPatchID("cylinder");
const polyPatch& cPatch = mesh.boundaryMesh()[patchID];
const surfaceScalarField& magSf = mesh.magSf();

scalar patchAreaTemp = gSum(notEqual(gamma.boundaryField()[patchID],0.0)
* pos(gamma.boundaryField()[patchID])
* magSf.boundaryField()[patchID]);

and compiling it gives the following error:

postProcessing.H:64: error: no matching function for call to 'notEqual(Foam::fvPatchField<double>&, double)'
/home/openfoam/OpenFOAM/OpenFOAM-1.4.1/src/OpenFOAM/lnInclude/Scalar.H:115: note: candidates are: bool Foam::notEqual(Foam::floatScalar, Foam::floatScalar)
/home/openfoam/OpenFOAM/OpenFOAM-1.4.1/src/OpenFOAM/lnInclude/Scalar.H:115: note: bool Foam::notEqual(Foam::doubleScalar, Foam::doubleScalar)

Is using notEqual requires to include some files.

Please comment.

Thanks in advance
With Kind Regards

philippose January 31, 2008 16:02

Hello again :-)! Hmmm.... l
Hello again :-)!

Hmmm.... looks like the function "notEqual" has not been defined for scalarFields.

I wonder if the "equal" and "notEqual" functions could be added on as a patch, or if it was left out for a specific reason.

Anyway... as a workaround which would introduce a slight error in the calculation, you can try this:

scalar patchAreaTemp = gSum((gamma.boundaryField()[patchID]/stabilise(gamma.boundaryField()[patchID],1. 0e-10))
* pos(gamma.boundaryField()[patchID])
* magSf.boundaryField()[patchID]);

So that way, if the value of gamma is zero, the result of the first operation would be zero.

On the other hand, if the value is not zero, you would get a number extremely close to unity, but not quite (though you could play around with the "1.0e-10" to suit your accuracy requirements).

I hope someone will respond with an easier solution :-)!

You could take a look at the "gather" function, which does the basic data collection for parallel runs to see if you can use that directly somehow.



hjasak January 31, 2008 17:27

OK, here goes
OK, here goes

1) Assume Guru position 1

2) Write code:
// You should not be comparing with zero
const scalar gammalLimit = 1e-3;

scalar sumCoveredArea =
gSum(pos(gamma.boundaryField()[patchID] - gammaLimit)

3) Release Guru position 1 (2 lines of code, I think...)

4) Finished.

- pos means "give me 1 if greater than zero and 0 otherwise
- all patches are present on all processors, so there's no danger in doing a global sum



philippose January 31, 2008 17:53

Hello Hrv, Great to hear fr
Hello Hrv,

Great to hear from you :-)! Was hoping that would happen :-)!

So... about the "pos" function... I was checking up in the file "scalar.H".... the reason why I took the trouble of all that stuff with "stabilise" was because the pos function works with:

if (value >= 0) then
return 1
return 0

So I cannot use that to check for a zero, since it checks for a "greater than or equal to" clause.

However, your suggestion is more elegant (guru like ;-)!) than mine :-)! So as usual... hats off :-)!

By the way... was there a reason why the "equal" and "notEqual" functions were not added to the functions available for scalarFields? And what do you say about adding those in too ??


jaswi February 2, 2008 14:18

Hello Hrv (Guru 1) and Philipp
Hello Hrv (Guru 1) and Philippose,

Thanks alot for the solution.

As usual your solution works with sheer elegance :-)

I will be needing a lot of tips from the gurus as I have undertaken a 3D stirred reactor simulation and it has to be with bubbles. Right now not much idea how to do that but then it was the same when I started working with OpenFOAM.

Thanks a lot to you guys

With Best Regards

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