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/)
-   -   Access boundaryMesh / boundaryField on cellZone (https://www.cfd-online.com/Forums/openfoam-programming-development/140381-access-boundarymesh-boundaryfield-cellzone.html)

Nucleophobe August 13, 2014 16:36

Access boundaryMesh / boundaryField on cellZone
 
Hi all:

I have a question similar to one posed in an earlier thread regarding the manipulation of cellZones.

I would like to calculate the wall shear stress on the boundary of a cellZone which I have created using topoSet. I think this would be something like:

Code:

            const label cellZoneID = mesh.cellZones().findZoneID("myCellZone");
            if (cellZoneID < 0)
            {
                FatalError
                    << "Unable to find cell zone " << "myCellZone" << endl
                    << exit(FatalError);
            }
            const cellZone& zone = mesh.cellZones()[cellZoneID];
            const cellZoneMesh& zoneMesh = zone.zoneMesh();
            const labelList& cellsZone = zoneMesh[cellZoneID];

          // Calculate WSS as in 'wallShearStress' utility:
            autoPtr<incompressible::RASModel> model
            (
                incompressible::RASModel::New(U, phi, laminarTransport)
            );
            const volSymmTensorField Reff(model->devReff());

            // Perform this calculation over the cell set only - how?
            scalarField zoneWSS = mag( (-mesh.Sf().boundaryField()[cellZoneID]/mesh.magSf().boundaryField()[cellZoneID]) & Reff.boundaryField()[cellZoneID] )

But I don't think "mesh.Sf().boundaryField()[cellZoneID]" is correct (this would access the patch corresponding to cellZoneID, not the cellZone, right?).

Can anyone give me some guidance on how to proceed? Thanks!

-Nuc

P.S.
Relevant thread:
http://www.cfd-online.com/Forums/ope...ne-volume.html
Quote:

Originally Posted by rob3rt (Post 267069)
... I know there is a function like mag(mesh.Sf().boundaryField()[cellZoneID][cI]) ... <-- This is what I'm looking for, but I'm not sure about the syntax


jhoepken August 14, 2014 08:35

Just a short question: Are there multiple boundary patches in the cellZone?

Nucleophobe August 14, 2014 10:01

Quote:

Originally Posted by jhoepken (Post 505970)
Just a short question: Are there multiple boundary patches in the cellZone?

In this case, there is only one boundary patch (a wall) and then some exposed internal faces.

Is it possible to query a patch within a cellZone?

jhoepken August 14, 2014 10:10

Why don't you create a faceZone that solely contains the boundary faces and just loop over them?

Nucleophobe August 14, 2014 10:14

Quote:

Originally Posted by jhoepken (Post 506002)
Why don't you create a faceZone that solely contains the boundary faces and just loop over them?

jhoepken,

I tried this, but the faceSet I created included internal faces in my bounding box.If I can create a faceSet from a patch, that would work, so I'll look into that.

Thanks!

Nucleophobe August 14, 2014 16:07

*EDIT: I got it - see bottom

Okay, I was able to create a faceSet of boundary faces only via the following topoSetDict code (the key - use of "action subSet"):
Code:

    {
        name  myFaceSet;
        type    faceSet;
        action  new;
        source  patchToFace;
        sourceInfo
        {
            name myPatch;
        }
    }
    {
        name  myFaceSet;
        type    faceSet;
        action  subset;
        source boxToFace;
        sourceInfo
        {
            box  (-0.045 -0.0123 -0.02) (-0.00209 0.0105 0.015);
        }
    }
    {

        name    myFaceZone;
        type      faceZoneSet;
        action    new;
        source  setToFaceZone;
        sourceInfo
        {
            faceSet myFaceSet;
        }
    }

So, now I have a faceZone containing global indices to the faces in my region of interest. However, I am having trouble querying these faces. For example, mesh.magSf() allows for accessing faces using their global index, but it only includes internal faces, not boundary faces.

Meanwhile, mesh.magSf().boundaryField() allows for accessing boundary faces by patch ID and local face ID, not global face ID.

How would I instead query the face area of the faces in my faceZone, which are boundary faces? Thanks again!
Code:

          // Example Code:
          scalar zoneFaceArea(0);

          forAll (facesZone, faceI)
          {
                // mesh.magSf() addresses internal faces only, while the indices from facesZone[faceI] address boundary faces...
                zoneFaceArea += mesh.magSf()[facesZone[faceI]];
          }


*SOLUTION:
To convert between global faceID and local, patch-based faceID, you can use the 'whichPatch' and 'whichFace' functions. So, something like the following:
Code:

          scalar zoneFaceArea(0);

          forAll (facesZone, faceI)
          {
                label facePatchID = mesh.boundaryMesh().whichPatch(faceI);
                label faceID = mesh.boundaryMesh()[facePatchID].whichFace(facesZone[faceI]);               

                zoneFaceArea += mesh.magSf().boundaryField()[facePatchID][faceID];
                // etc...
          }

I found references to these functions in "src/fvOptions/sources/derived/effectivenessHeatExchangerSource/effectivenessHeatExchangerSource.C"

Thanks for the help jhoepken! I hope your book is coming along well - it looks interesting.

jhoepken August 15, 2014 07:25

Great that you've figured it out! I was busy and could not answer, sorry :).

Andy_bm March 28, 2015 12:08

I am interested of this topic.

I made faceZone with snappyHexMesh using stl file like:
Code:

faceZone1
{
level (1 1);
cellZone  cz1;
faceZone fz1;
...
}

And I want get access to pressure and U fields on this surface (fz1) during calculation. How it can be implemented? I tried to use code from this topic but has no effect.

Nucleophobe March 28, 2015 12:14

Andy,

Can you post your code so we can see what's going on? You need to setup a few things before you can access faceZone data.

Andy_bm March 28, 2015 13:25

It not easy because there is no way to see it in my project now. I tried different variants.
Code:

label zID = mesh.facesZone().findZoneID(zName);
const faceZone& facesZone = mesh.faceZone()[zID];
 
forAll(facesZone, I)
{
Here I want get access to pressure field. If I try code as
p.boundaryField()[zID][i];
I get acces to patch field with ID=zID
 
If I try
facePatchID = mesh.boundaryMesh().whichPatch(zID);
fID = mesh.boundaryMesh[facePatchID].whichFace(facezZone[zID])
I get error during calculation.
}

Sorry, may be errors because I entered the code as I remember.

Andy_bm April 1, 2015 10:51

Do you have any idea?

Nucleophobe April 1, 2015 10:58

Can you post your error message too? I'll dig up my code later and see how the syntax differs.

BTW: you have a typo in your code:
facezZone[zID]

facesZone[zID]

Andy_bm April 5, 2015 12:43

PrintStack error. I think it is because faceZone length array and numder iteration in cycle is different
Code:

facezZone[zID]
facesZone[zID]

It's my mistake. All right in code

Andy_bm April 7, 2015 04:19

Maybe there is function in mesh which get faceID and return cellID?

Andy_bm April 30, 2015 18:25

I solved this problem but it is not work in parallel. Because there are boundaryfaces on processor and faces are duplicate. How can I delete duplicate faces on processor?

giack February 26, 2016 10:14

Hi to all,

I'm also interested to the topic.
How did you solve the PrintStack error?

Thanks
Giacomo

pvpnrao September 15, 2016 14:23

Spanwise averaging fields within a cellSet.
 
Ken
Are you ware of the spanwise averaging utility "postSpanwiseAverage" posted by some one on this forum. I need to use it, but wish to calculate the spanwise average of a field in particular cellSet. Do know how to do that

AbdulazizAlkandari November 13, 2019 12:27

Hi Nucleophobe,

I managed to follow all your steps successfully to loop over all faces of a facezone which was created as a subset. However, I cant seem to be able to run in parallel (edit: or series) even though im using the reduce(facesum, sunOp<scalar>()) .The solver crashes with the following error:

[1] #0 Foam::error::printStack(Foam::Ostream&) at ??:?
[1] #1 Foam::sigSegv::sigHandler(int) at ??:?
[1] #2 ? in "/lib/x86_64-linux-gnu/libc.so.6"
[1] #3 Foam::OutputInfoFunctionObject::execute() at ~/OpenFOAM/OpenFOAM-v1612+/src/OpenFOAM/lnInclude/polyPatch.H:392
[1] #4 Foam::functionObjectList::execute() at ??:?
[1] #5 Foam::Time::run() const at ??:?
[1] #6 ? at ??:?
[1] #7 __libc_start_main in "/lib/x86_64-linux-gnu/libc.so.6"
[1] #8 ? at ??:?
[mne-alra12:22426] *** Process received signal ***
[mne-alra12:22426] Signal: Segmentation fault (11)
[mne-alra12:22426] Signal code: (-6)
[mne-alra12:22426] Failing at address: 0x3ea0000579a

My code:
const label stagID = mesh().faceZones().findZoneID("StagZone");
const faceZone& zone = mesh().faceZones()[stagID];
const faceZoneMesh& zonemesh = zone.zoneMesh();
const labelList& stagcells = zonemesh[stagID];

forAll( stagcells, facei)
{

label facePatchID = mesh().boundaryMesh().whichPatch(facei);
label faceID = mesh().boundaryMesh()[facePatchID].whichFace(stagcells[facei]);

faceArea += (mesh().magSf().boundaryField()[facePatchID][faceID]);


}


reduce(faceArea,sumOp<scalar>());


All times are GMT -4. The time now is 23:47.