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/)
-   -   Confusion face-addressing for surfaceField (https://www.cfd-online.com/Forums/openfoam-programming-development/75223-confusion-face-addressing-surfacefield.html)

ngj April 19, 2010 17:41

Confusion face-addressing for surfaceField
 
Hi all

I am confused with respect to the addressing of boundary face values for surfaceFields. Assume that the index "fLabelGlobal" is for a face on a boundary in terms of global indexing and "fLabelLocal" is targeting the same face, however in term of index locally on the boundary field. Then I can produce identical results with:

mesh.Cf()[fLabelGlobal]

and

scalarField cf = mesh.Cf().boundaryField()[correctIndex];
cf[fLabelLocal];

However trying to do

phi[fLabelGlobal]

produces garbage whereas

scalarField phiw = phi.boundaryField()[correctIndex];
phiw[fLabelLocal];

produces the correct result.

Both mesh.Cf() and phi are surfaceFields, however they appear to behave differently, what am I doing wrong?

By the way, I am working on cell level and need to target phi on all faces irrespectively of them being internal or boundary faces. I have made a hack to yield phi correctly, however it is painfully slow, thus any help is appreciated.

Best regards,

Niels

herbert April 20, 2010 05:25

Hi Niels,

the only difference I see is that phi is a surfaceScalarField while mesh.Cf() is a surfaceVectorField. Might this be the problem?

Maybe there is a special boundary treatment for surfaceScalarFields only. I'll keep on trying.

Regards
Stefan

brosemu January 19, 2011 17:03

Hi Niels,

Did you ever figure out the issue? I'm struggling with the same issue, trying to map faces on a boundaryField from a subMesh back to the full mesh.

I have an fvMeshSubset called evaluationMesh and it shares common faces on patch 3 with the full mesh.

Code:

volVectorField u(IOobject("u", runTime.timeName(), evaluationMesh.subMesh(), IOobject::NO_READ, IOobject::AUTO_WRITE), evaluationMesh.subMesh(), Foam::vector(0,0,0));

patchi = 3;

// This gives the correct mapping between patches
const label& patchI = evaluationMesh.patchMap()[patchi];

// calcU returns a vectorField
u.boundaryField()[patchi] = calcU(evaluationMesh.subMesh().C().boundaryField()[patchi]);
   
// Map back to full field
forAll(u.boundaryField()[patchi],facei)
{
        // This is where the issue is becuase facei counts from 0 -> nFaces on patchi of boundaryField
        // when I need it to index in the global sense for the mapping to be correct
        const label& faceI = evaluationMesh.faceMap()[facei];
               
        U.boundaryField()[patchI][faceI] == u.boundaryField()[patchi][facei];
}

Notice the difference between patchi / patchI and facei / faceI - capital I denotes full mesh, little i denotes submesh. Also, little u is the volVectorField on the subMesh.

Any insight?

Thanks!

ngj January 20, 2011 04:39

Hi

As you do note, you merely need to get hold on the global face-count for facei, then you will get a global faceI which needs to be transformed into a local patch faceI. I have recently done something like that:

Code:

const fvPatchList & patches = cMesh_.boundary();
const fvPatchList & gpatches = mesh_.boundary();
const label nInternalFacesGlobal = mesh_.nInternalFaces();

forAll ( patches, patchi )
{
    const fvPatch & curPatch = patches[patchi];
   
    if ( curPatch.type() != "empty" )
    {
        label start = curPatch.patch().start();
           
        scalarField & gw = gammafC.boundaryField()[patchi];
           
        forAll ( gw, facei )
        {
            label gfacei = faceMap_[start + facei];
               
            if ( gfacei >= nInternalFacesGlobal )
            {
                 
                label gpatchID = mesh_.boundaryMesh().whichPatch(gfacei);
                label gstart  = gpatches[gpatchID].patch().start();
                label lstart  = gfacei - gstart;
                   
                const scalarField & ggw = gammaf.boundaryField()[gpatchID];
                   
                gw[facei]  = ggw[lstart];
            }
            else
            {
                gw[facei]  = gammaf[gfacei];
            }
        }
    }
}

Here mesh_ is the global mesh and cMesh_ is the submesh. gammaf is a global surfaceScalarField and gammafC is a surfaceScalarField on cMesh_.

I hope this can help you overcome your problems.

Best regards,

Niels

P.S. Note that you need to consider the directions of the patch normals when mapping phi. This is due to the definition of a surface normal vector pointing to the outside on a patch, however a face on the global mesh being turned into a patch face has not been constructed originally with this constraint, hence it might be pointing in the wrong direction as a patch face.

brosemu January 20, 2011 19:56

Hi Niels,

That fixed it! The two pieces of information I needed where that you can access the global starting index (of course you can!) and that the globalIndex = startIndex + localIndex (of course it does!).

Thanks again.

hawkeye321 October 2, 2012 16:40

addressing in surfacescalarfield
 
Do you guys know how the elements of surfacescalarfield are addressed? for example which which position does phi[celli] exactly refer to?


All times are GMT -4. The time now is 10:48.