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/)
-   -   Neumann boundary conditions (https://www.cfd-online.com/Forums/openfoam-programming-development/79066-neumann-boundary-conditions.html)

Martin80 August 11, 2010 09:35

Neumann boundary conditions
 
Hi,

I want to change my boundary conditions during runtime. For the Dirichlet conditions I have found a way to set up the conditions in the code:

I have choosen fixedValue for the boundary type and I updated it in the code using:
U.boundaryField()[patchI]== mynewScalarField;

I have tried the same with fixedGradient type for a Neumann Condition but it doesn't update the gradient value. (I have reviewed it with .snGrad()).

Maybe someone can give me a useful hint,
thanks, m.

herbert August 16, 2010 07:47

Hi Martin,

you have to do a refCast. Example:
Code:

fixedGradientFvPatchVectorField& gradUPatch=refCast<fixedGradientFvPatchVectorField>(U.boundaryField()[patchI]);
scalarField& gradUField =  gradUPatch.gradient();

After this you can edit gradient values in gradUField.

Of course you have to include "fixedGradientFvPatchFields.H" in your header.

Regards,
Stefan

astein August 16, 2010 08:33

Hi!
snGrad() has nothing to do with the gradient which you want to impose with your boundary condition, it is some geoemetrical quantity.

The fvPatchField is a field of quantities, which are applied as fixed gradients. Therefore, you have to write the wanted values to the field the same way you do it for the fixedValue stuff.

I hope you get the point...
Cheers, Andreas.

Martin80 August 16, 2010 13:53

Hi Stefan,
I have already got the same answer from somebody else but thank you very much - this is exactly what I was seeking for. [.gradient() is not a member function of "volVectorField" but of "fixedGradientFvPatchVectorField"].

Hi Andreas,
I don't think u r right, U.boundaryField()[patchI].snGrad() in that case should show me the current boundary condition of the fixedGradient bc object.

B.r.,
Martin.

ubaid August 16, 2010 13:59

HAve u guys got the solution how to update the value of gradient, I think my problem is also similar to yours.

that is expressed below:

volScalarfield field
(
IOobject(fieldName,runtTime.timeName(),mesh,IOobje ct::NO_READ,IOobject::AUTO_WRITE),
mesh,
dimensionedScalar(fieldName,dimTemperature, 200),
"fixedGradient"
);
forAll(field.BoundaryField(),patchID)
{
field.boundaryField()[patchID]==30;
}

As an output of this code am getting something different.
that is.

boundaryField
{
Inlet
{
type fixedGradient;
gradient uniform 0;
}

and so on;
}

but I am interested to get output as below:

boundaryField
{
inlet
{
type fixedGradient;
gradient uniform 30;

}
}

astein August 17, 2010 03:03

Martin,
at the end, its the same.

What herbert is proposing is to copy (with the refCast) the reference of the fvPatchField to a new vectorField and editing THAT. Because of the reference, that still modifies the original field.

But you could write to your fixedGradientFvPatchVectorField directly, without giving it a new name. Just try it :-)

And - snGrad is definitely returning some geometrical stuff from the mesh, take a look at doxygen.

As long as it works there is no need to worry... ;)
Have fun,
Andreas.

ubaid August 17, 2010 07:31

Quote:

Originally Posted by astein (Post 271716)
Martin,
at the end, its the same.

What herbert is proposing is to copy (with the refCast) the reference of the fvPatchField to a new vectorField and editing THAT. Because of the reference, that still modifies the original field.

But you could write to your fixedGradientFvPatchVectorField directly, without giving it a new name. Just try it :-)

And - snGrad is definitely returning some geometrical stuff from the mesh, take a look at doxygen.

As long as it works there is no need to worry... ;)
Have fun,
Andreas.



Thanks, surely it works, I read this thread little bit late thoroughly and atlast i did it.

cfm September 6, 2010 05:37

Help Neumann boundary condition in fluent
 
Hi!!
I need to define an output Neumann boundary condition using fluent. the condition is dc/dn=0, where c is the concentration of a certain species and n is the normal versor to the output face.
How can I do this? Thanks!

Cyp October 14, 2010 09:28

Quote:

Originally Posted by herbert (Post 271623)
Hi Martin,

you have to do a refCast. Example:
Code:

fixedGradientFvPatchVectorField& gradUPatch=refCast<fixedGradientFvPatchVectorField>(U.boundaryField()[patchI]);
scalarField& gradUField =  gradUPatch.gradient();

After this you can edit gradient values in gradUField.

Of course you have to include "fixedGradientFvPatchFields.H" in your header.

Regards,
Stefan


Hi Stefan and everybody,

I trying to implement neumann BC with your method but I had a fail during the compilation. I have merely copy your piece of code in my main.C file and I included "fixedGradientFvPatchFields.H" in my header.

I get the following error :

Code:

applications/twoDarcyF> wmake
Making dependency list for source file twoDarcyF.C
SOURCE=twoDarcyF.C ;  g++ -m64 -Dlinux64 -DWM_DP -Wall -Wno-strict-aliasing -Wextra -Wno-unused-parameter -Wold-style-cast -Wnon-virtual-dtor -O3  -DNoRepository -ftemplate-depth-40 -I/gemp/csoulain/OpenFOAM/OpenFOAM-1.7.0/src/finiteVolume/lnInclude -IlnInclude -I. -I/gemp/csoulain/OpenFOAM/OpenFOAM-1.7.0/src/OpenFOAM/lnInclude -I/gemp/csoulain/OpenFOAM/OpenFOAM-1.7.0/src/OSspecific/POSIX/lnInclude  -fPIC -c $SOURCE -o Make/linux64GccDPOpt/twoDarcyF.o
twoDarcyF.C: In function ‘int main(int, char**)’:
twoDarcyF.C:74: error: invalid initialization of reference of type ‘Foam::scalarField&’ from expression of type ‘Foam::Field<Foam::Vector<double> >’
make: *** [Make/linux64GccDPOpt/twoDarcyF.o] Erreur 1


Do you have any idea where I am wrong ?

Regards,
Cyp

Martin80 October 14, 2010 09:44

It should be:


vectorField& gradUField = gradUPatch.gradient();

(in case U is a volVectorField)

M.

Cyp October 14, 2010 10:26

Ok. Thank you very much. It compiles now.


But in case U is a volScalarField (a pressure field for example)? The code of Hebert should works, shouldn't it ?

Martin80 October 14, 2010 10:51

No, i think in that case (for a volScalarField) you have to modify the first expression of Stefan's code in an appropriate way.
M.

Cyp October 14, 2010 12:33

I have a problem of understanding: the gradient of a scalar should be a vector. So the following snippet should work:

Code:

label patchID = mesh.boundaryMesh().findPatchID("inlet");

fixedGradientFvPatchVectorField& gradUPatch=refCast<fixedGradientFvPatchVectorField>(p.boundaryField()[patchID]);
scalarField& gradUField =  gradUPatch.gradient();

gradUField = -(inv(M)&U)+rho*g;

where M is a tensor, U the velocity field (vector), rho a volScalarField, and g the vector acceleration.

In fact, it compiles but fails while running:

Code:

Time = 0.1


--> FOAM FATAL ERROR:
Attempt to cast type fixedValue to type fixedGradient

    From function refCast<To>(From&)
    in file /opt/openfoam171/src/OpenFOAM/lnInclude/typeInfo.H at line 114.

FOAM aborting

I can't see my mistake..

Martin80 October 14, 2010 12:49

You define the outer normal gradient (grad p * n) [n is the surface outer normal direction]

let p be a scalarF and V a vectorF then:

grad(p) is a vectorF -> (grad(p)) *n is a scalarF
grad(V) is a tensorF -> (grad(V)) *n is a vectorF

I hope it helps, M.

Cyp October 14, 2010 13:14

Thank you very much Martin. It helps me much in the understanding !

So I changed the code as :

Code:


label patchID = mesh.boundaryMesh().findPatchID("inlet"); 
fixedGradientFvPatchScalarField& gradUPatch=refCast<fixedGradientFvPatchScalarField>(p.boundaryField()[patchID]);
scalarField& gradUField =  gradUPatch.gradient();

Now, according to your definition, if I understand correctly, I need to get the projection of my field -(inv(M)&U)+rho*g on the patch : (-(inv(M)&U)+rho*g ) *n. Is it possible to do such a thing ?

Cyp October 14, 2010 13:41

I think it could work with :

Code:

gradUField = linearInterpolate(-(inv(M)&U)+rho*g) & mesh.Sf();

Martin80 October 14, 2010 14:14

The normal surface vector field on the boundarypart patchID is:
vectorField n = mesh.Sf().boundaryField()[patchID]


Take care that the left part of your calculation is finally also a vectorField on the appropriate domain (boundaryField()[patchID]).
M.

Cyp October 18, 2010 11:53

Hi Martin!

Thank you very much for your answer. I am not sure to understand very well...

I tried:

Code:

label patchID = mesh.boundaryMesh().findPatchID("inlet");
fixedGradientFvPatchScalarField& gradUPatch=refCast<fixedGradientFvPatchScalarField>(p.boundaryField()[patchID]);
scalarField& gradUField =  gradUPatch.gradient();

vectorField n = mesh.Sf().boundaryField()[patchID];

and either
Code:

gradUField = (-(inv(M)&U)+rho*g)&n
or
Code:

gradUField = (-(inv(M)&U)+rho*g)*n
or
Code:

gradUField = linearInterpolate(-(inv(M)&U)+rho*g)&n
but it does not compile... Do you see my mistake ??

Cyp October 25, 2010 10:28

Hi!


I succed in the compilation using this piece of code :

Code:

        label patchID = mesh.boundaryMesh().findPatchID("inlet");

        fixedGradientFvPatchScalarField& gradUPatch=refCast<fixedGradientFvPatchScalarField>(p.boundaryField()[patchID]);
        scalarField& gradUField = gradUPatch.gradient();
       
        vectorField n = mesh.Sf().boundaryField()[patchID];

        vectorField UU_beta = U_beta.boundaryField()[patchID];

        tensorField MM_beta = M_beta.boundaryField()[patchID];

        tensorField invMM_beta=inv(MM_beta);

        gradUField = -((invMM_beta&UU_beta)&n)+(rho_beta.boundaryField()[patchID]*(g.value())&n);


I set up a fixedValue at the inlet for my U_beta field but when I plot the results, the U_beta value is different that the one I chose...

Did I miss something ??

Regards,
Cyp

herbert October 26, 2010 05:00

Please realize that you are editing the BC for p with your code
Quote:

Originally Posted by Cyp (Post 280663)
Code:

        fixedGradientFvPatchScalarField& gradUPatch=refCast<fixedGradientFvPatchScalarField>(p.boundaryField()[patchID]);

If you want to edit BC for U, you have to change it in the following way
Code:

      fixedGradientFvPatchScalarField& gradUPatch=refCast<fixedGradientFvPatchScalarField>(U.boundaryField()[patchID]);
Regards,
Stefan


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