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/)
-   -   Assigning boundary value to every cell above it (https://www.cfd-online.com/Forums/openfoam-programming-development/133209-assigning-boundary-value-every-cell-above.html)

CHARLES April 11, 2014 15:33

Assigning boundary value to every cell above it
 
Hello,

I'm stuck on something that seems rather trivial so I was hoping maybe somebody could give me a hand... :D

I would like to assign the value of friction velocity, utau, AT A WALL (for a given x-coordinate) to every cell above it (i.e: utau(x=i,y=allCells)=utau(x=i,y=0)).

My problem is that when I compute utau, I only get values at the boundaries, while the rest of the volScalarField is left as its initialized value (0). When I look at the output in the time step directories and ParaView, I can see that there are utau values for solid boundaries only, not for cell centers... which makes sense given how I defined utau (see below).

The question:
How can I tell OpenFOAM to assign the value of utau (at the wall) to all of the cells above it at each x-location?

Reason for doing this:
I am adding a scalar term to the dissipation equation that has utau in it. Since the solver loops through each cell, I need to assign the value of utau (at the wall) to each cell center in the corresponding column.
I'm assuming that utau will vary as you move in the x-direction since dUdy will be different.

Below are the definitions of utau and my implementation in OpenFOAM. I understand that the code below only gives me utau at the boundaries, I just don't know how to tell it to assign that value to all cells above.
I aplogize, for my coding skills aren't the best :(

utau = sqrt(tau_wall/rho) = sqrt(mu * dUdy / rho) = sqrt( nu * dUdy)

in OpenFOAM:

Code:

forAll(utau.boundaryField(), patchi)
    {
        utau.boundaryField()[patchi]=
        sqrt
                        (
                            nu()*mag(U_.boundaryField()[patchi].snGrad())
                        );
    }

Thanks ahead of time!

fumiya April 11, 2014 22:55

Hi,

You can access the cells next to a patch using faceCells().

Code:

forAll(mesh.boundary()[patchI], faceI) //patchI: label of your target patch
{
    utau[mesh.boundary()[patchI].faceCells()[faceI]] = ...
}

Hope this helps,
Fumiya

------------------------------------------
My slides about OpenFOAM:) (http://www.slideshare.net/fumiyanozaki96)

CHARLES April 15, 2014 12:59

Hi Fumiya,

Thank you for replying!

I'm still a little confused about what you are suggesting... What do you mean by 'target patch'?
Also, how would I assign a single value (utauw at the boundary) to every cell above it so that OpenFOAM doesn't complain about assigning a Foam::Field<double> to a 'double' ?

I have looked over some existing code and I'm implementing the following:

Code:

 
const fvPatchList& patcha = mesh_.boundary();
    forAll(patcha, patchi)
    {
        const fvPatch& currPatch = patcha[patchi];
        if (isType<wallFvPatch>(currPatch))
        {
            utauw.boundaryField()[patchi] = sqrt
                        (
                            nu()*mag(U_.boundaryField()[patchi].snGrad())
                        );
            forAll(currPatch, facei)
            {
                label faceCelli = currPatch.faceCells()[facei];
                // Assign utau from boundary to face values in internal field
                utau[faceCelli] = utauw[patchi];
            }
        }
    }

The code above calculates utauw (at the wall) correctly, but it does not assign its value to utau (cells above boundary). As a matter of fact, utau still holds the value at which it was initialized at.

I need to somehow store the value produced by
Code:

            utauw.boundaryField()[patchi] = sqrt
                        (
                            nu()*mag(U_.boundaryField()[patchi].snGrad())
                        );

at the boundary faces.

fumiya April 15, 2014 17:36

Hi CHARLES,

You might want to try

utau[faceCelli] = utauw.boundaryField()[patchi][facei];
//RHS: utauw value at each boundary face(label: facei) on the boundary(label: patchi)

instead of

utau[faceCelli] = utauw[patchi];

in your code.

Hope this helps,
Fumiya

CHARLES April 15, 2014 23:19

Fumiya,

I'm sorry but after re-reading my post, I realized that I wasn't very clear.

What you suggested allowed the script to compile and run! It also gave the results you had expected: the utauw value (at the boundary) is being assigned to utau (at the cell centers in contact with the boundary). utau is now a nonuniform list, which also solved part of the problem that I was having before.

However, what I intended to do was to copy the value of utauw (from the boundary) to ALL cell centers above it, not just the boundary cell centers.

I tried to write another forAll loop that would loop through all of utau, which would compile but I get a segmentation fault in the log file on the first iteration. I think I'm trying to assign a boundary's value to a single cell, which may be the cause of the problem.

Code:

label PatchID = mesh_.boundaryMesh().findPatchID("plate");
label FaceID = 0;
forAll(utau, celli)
{
    utau[celli] = utauw.boundaryField()[PatchID][FaceID];
}

Code:

Starting time loop

Time = 1e-05

DILUPBiCG:  Solving for Ux, Initial residual = 1, Final residual = 1.36617e-07, No Iterations 1
DILUPBiCG:  Solving for Uy, Initial residual = 1, Final residual = 1.36614e-07, No Iterations 1
DICPCG:  Solving for p, Initial residual = 0.999805, Final residual = 9.67079e-07, No Iterations 531
time step continuity errors : sum local = 3.21009e-14, global = 1.1476e-17, cumulative = 1.1476e-17
[0] #0  Foam::error::printStack(Foam::Ostream&) in "/home/sebastian/OpenFOAM/OpenFOAM-2.2.0/platforms/linux64GccDPOpt/lib/libOpenFOAM.so"
[0] #1  Foam::sigSegv::sigHandler(int) in "/home/sebastian/OpenFOAM/OpenFOAM-2.2.0/platforms/linux64GccDPOpt/lib/libOpenFOAM.so"
[0] #2  in "/lib/x86_64-linux-gnu/libc.so.6"
[0] #3  Foam::incompressible::RASModels::SPLRRIP::correct() in "/home/sebastian/OpenFOAM/sebastian-2.2.0/platforms/linux64GccDPOpt/lib/libmyIncompressibleRASModels.so"
[0] #4 
[0]  in "/home/sebastian/OpenFOAM/OpenFOAM-2.2.0/platforms/linux64GccDPOpt/bin/simpleFoam"
[0] #5  __libc_start_main in "/lib/x86_64-linux-gnu/libc.so.6"
[0] #6 
[0]  in "/home/sebastian/OpenFOAM/OpenFOAM-2.2.0/platforms/linux64GccDPOpt/bin/simpleFoam"
[navier1:20000] *** Process received signal ***
[navier1:20000] Signal: Segmentation fault (11)
[navier1:20000] Signal code:  (-6)
[navier1:20000] Failing at address: 0x3eb00004e20
[navier1:20000] [ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x364a0) [0x7f4ee6cbd4a0]
[navier1:20000] [ 1] /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x35) [0x7f4ee6cbd425]
[navier1:20000] [ 2] /lib/x86_64-linux-gnu/libc.so.6(+0x364a0) [0x7f4ee6cbd4a0]
[navier1:20000] [ 3] /home/sebastian/OpenFOAM/sebastian-2.2.0/platforms/linux64GccDPOpt/lib/libmyIncompressibleRASModels.so(_ZN4Foam14incompressible9RASModels7SPLRRIP7correctEv+0x667) [0x7f4edf6d1b97]
[navier1:20000] [ 4] simpleFoam() [0x419c45]
[navier1:20000] [ 5] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7f4ee6ca876d]
[navier1:20000] [ 6] simpleFoam() [0x41b49d]
[navier1:20000] *** End of error message ***

btw, thank you for explaining the boundary field indexing!

CHARLES April 18, 2014 17:30

I believe I may have solved the segmentation problem...

However, I still have a few questions about the following part of the program:
Code:

forAll(Boundaries, patchi) //loops through boundaries
{
            utauw.boundaryField()[patchi] =
            sqrt
                        (
                            nu()*mag(U_.boundaryField()[patchi].snGrad())
                        );
}

1. Is the gradient, snGrad(), being calculated for the patch as a whole? or is it being done on a face-by-face basis?
The reason I ask is because the value of utauw that is output to the time directory doesn't change (for a flat plate) but one would expect that the gradient of the velocity would be a function of the streamwise-distance along the plate.
When I look at utauw for a different geometry, like a 2D bump, it varies in the time directory output.

2. Why is the following not correct
Code:

        utau2[faceCelli] =            sqrt
                        (
                            nu()*mag(U_.boundaryField()[patchi][facei].snGrad())
                        );

Error:
Code:

SPLRRIP.C: In member function ‘virtual void Foam::incompressible::RASModels::SPLRRIP::correct()’:
SPLRRIP.C:526:72: error: ‘const class Foam::Vector<double>’ has no member named ‘snGrad’
make: *** [Make/linux64GccDPOpt/SPLRRIP.o] Error 1

But it will work if this is done instead:
Code:

                      utauw.boundaryField()[patchi] =
            sqrt
                        (
                            nu()*mag(U_.boundaryField()[patchi].snGrad())
                        );
            forAll(currPatch, facei)
            {
                label faceCelli = currPatch.faceCells()[facei]; //indexed face in current patch
                // Assign utau[on indexed cell face] value from utauw[on boundary][at each boundary face]
                utau[faceCelli] = utauw.boundaryField()[patchi][facei];
            }



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