nuEff()()[patchI] and nuEff()
Dear all,
I have a simple question about the following. In the fixedShearStress BC we find this: Code:
const label patchI = patch().index(); At least nuEff is empty: Code:
nuEff Code:
Info<< turbModel.nuEff() << endl; If I use this one, that is exactly the same, I get some complete different values: Code:
scalarField nuEff2(turbModel.nuEff()()[patch().index()]); Code:
Info<< "nueff: " << turbModel.nuEff()()[patchI] << endl; Code:
scalarField nuEff2(turbModel.nuEff()()[patch().index()]); At least the BC will fail because we use nuEff to divide: Code:
operator==(tauHat*(tauHat & (tau0_*(1.0/(ry*nuEff)) + Uc))); Finally, if we output the turbModel.nuEff() we get the correct values: Code:
. I also made a bug report now because it seems really strange. http://openfoam.org/mantisbt/view.php?id=2020 |
Hi,
Maybe I am missing something but, turbulenceModel::nuEff() returns tmp<volScalarField>, so nuEff()() (http://foam.sourceforge.net/docs/cpp...2d975c8876d3d6) is volScalarField and nuEff()()[index] should be scalar. Yet there is turbulenceModel::nuEff(label patchI), which returns viscosity on a patch. Could you post whole code snippet (so it could be compiled and tested)? |
Hey Bruno,
thanks for the reference about ()() ... here is the link to the file. If you are correct and ()()[patchI] returns a scalar, why we use a scalarField nuEff than and can you tell me what scalar is returned? Mean value of the patch or sth. like that? http://www.openfoam.com/documentatio...36_source.html |
Hi,
Not quite Bruno, but OK ;) Do you talk about line 112 of fixedShearStressFvPatchVectorField.C? It uses turbulenceModel::nuEff(label patchI), which returns tmp<scalarField> (http://www.openfoam.com/documentatio...4f85f6644d2d6a). |
1 Attachment(s)
Aaa its version 3.0 Here it the file I was talking about...
|
Quote:
Code:
Return the effective viscosity on patch. |
You have scalarField with the size of the patch and it is has scalar for each face value.
Though BC uses this - turbModel.nuEff()()[patchI] - strange construction, turbulenceModel class has nuEff(label patchI) method even in 2.3.1. |
Hi,
Henry changed it: https://github.com/OpenFOAM/OpenFOAM...1fe57e8a140c7c For 3.0.x it is working now but for 2.3.1 I get an error if I use the code you (or henry) mentioned: Code:
fixedShearStress/fixedShearStressFvPatchVectorField.C: In member function 'virtual void Foam::fixedShearStressFvPatchVectorField::updateCoeffs()': |
Hi,
Even in 2.3.1 there are two types of turbulence models ones in src/turbulenceModels and another in src/TurbulenceModels (surprise, surprise). First type does not have nuEff(const label), second type has it and for RASModel it is implemented as: Code:
//- Return the effective viscosity on patch Code:
//- Return the laminar viscosity for patch Code:
//- Return the turbulence viscosity on patch Code:
nuEff = turbModel.nuEff()()[patchI] Code:
scalarField nuEff(turbModel.nuEff().boundaryField()[patchI]); Code:
transport().nu(patchI) Code:
scalarField nuEff(transport().nu(patchI) + nut().boundaryField()[patchI]); |
Hi,
I will try it tomorrow but today I tried it with boundaryField() without success. Maybe I made a simple mistake. Thanks in advance. |
I think there might also be problems with memory management. You receive a tmp<volScalarField> without storing it, and only access the boundary. I had a similar issue before and for me it helped to initialize a copy of the volScalarField before accessing the patch values like this:
volScalarField copy(turb->nuEff()); Afterwards you can use the boundaries of the copied field without worrying about the scope of the classes contained in the temporary object. In my case I even regarded it as a bug or atleast a design error. |
Hey,
thanks for the hint. At last the code has to be: Code:
nuEff = turbModel.nuEff()().boundaryField()[patchI]; |
strange things explained
Hello Tobi.
First thanks for your tuto and videos. Good job which could help some people and help OF to be more widely used than it is:) For your problem described here, Alexeym gave you good answer (using turbModel.nuEf()().boundaryField()[patchI]). To complete the post, I can give you some answers to the "strange" things you have mentioned in your first post. All things are related to the fact that turbModel.nuEff()()[patchI] (which is clearly a bug) is a scalar as mentioned by alexeym. A) What happens is the following: scalarField nuEff --> create a scalarField of size 0 nuEff = turbModel.nuEff()()[patchI] --> it is the UList<Type>::operator =(Type& v) (with Type=scalar) which assign all values of the List to v. But do nothing here since nuEff is of size 0! So nuEff is still empty list and Info << nuEff gives 0(). B) Other thing: your "scalarField nuEff2(turbmodel.nuEff()()[patchI])"... In fact, you try to construct a scalarField with a constructor scalarField (scalar& v) But this constructor doesn't exist... You have scalarField(label i, scalar v) (build a scalarField of size i and all values equal v) but clearly it is not this one you use. In fact, you use the base constructor scalarField(label i) which construct a scalarField of size i and no prescribed values (so compiler dependant / something like VSMALL for most compilers). And what is your i? The integer part of the scalar turbModel.nuEff()()[patchI] (124 for your example). These things explain what you have seen. |
Dear Thomas,
thanks for completing the topic and the feedback to my webpage. I am familiar with c++ but the error reported here was from a collegue in the german openfoam forum, that I just investigated during other investigations (: So at last I wanted to report you the bug, learn new things (thanks to you and Alexeym) but I did not investigate into the code deeply and of course I am not a FOAM - code expert (what function will return what or what is doing that). Its good that there are people like you that will clear the questions. So just one question. If I will create my scalarField nuEff with the size of the real field (lets say 200), and use Code:
nuEff = turbModel.nuEff()()[patchI] Nice dreams, |
Well if you write:
" scalarField nuEff(200) // create a scalarField with size 200 (not yet inialized here) .... nuEff = turbModel.nuEff()()[patchI] // assign all values of the scalarField as equal to the scalar on the right; comes from UList::operator =(scalar &v); doesn't change the size of the container as said in th previous post " at end, all the 200 values of the nuEff list will be equal to the same scalar value turbModel.nuEff()()[patchI]. It takes sense from informatic point of view but it is clearly not what you want I think. You should prefer the scalarField nuEff being equal to the scalarField turbModel.nuEff()().boundaryField()[patchI]. For this, you must use alexeym correct expression: " scalarField nuEff // create zero sized List (size doesn't matter here -- see later) nuEff = turbModel.nuEff()().boundaryField()[patchI] // it is the UList::operator =(UList& f) function. This function resizes the calling list (nuEff here) to the size of the called one (f in the prototype / turbModel..... in the example -- this is why the instanciation of nuEff as a zero sized list doesn't matter) and equals the values. " |
Quote:
I have a problem with nuEff() because as you said it creates list with size zero. How to force nuEff() to create a list of mesh size? |
Basically I overriden nu() to return my volScalarField.
And Now I get the error in nuEff() = this->nut() + this->nu() that nut() returns zero size list and nu() returns the size equal to e.g. 1400 So the sizes are not equal during summation. So I am wondering how to force nut() to return the same list size as nu()?? |
Hi
In the RASModel.H we have a function nuEff() Code:
//- Return the effective viscosity Code:
Foam::tmp<Foam::volScalarField> nu() When in the UEqn.H I have a code Code:
turbulence->divDevReff() How can I change the code to nut() returns also mesh size list? |
Quote:
I found how to solve the problem. I had something like this Code:
Foam::tmp<Foam::volScalarField> Code:
Selecting incompressible transport model Helium When I changed the nuCalc() function like this: Code:
Foam::tmp<Foam::volScalarField> Can anybody explain why this second solution works and the first doesn't? |
Can you tell us how you access the field nuHelium() in your solver.
|
Hi Tobi,
I have a class that derives from singlePhaseTransportModel class. Inside this class is a pointer to viscosity model. This pointer was private and now I changed it into protected to be able to use it. So I have an access to viscosity model and nu is calculated inside helium viscosity model class as shown in my previous post. |
Okay, and how do you access the function? I mean, you should have something like that somewhere:
Code:
volScalarField foo = pointerToModel->nuHelium(); |
yes it is inside singlePhaseTransportModel
Code:
Foam::tmp<Foam::volScalarField> Why are you asking? |
Hi, actually I ment something different but it does not matter. I guess I know the answer to your question:
Code:
Foam::tmp<Foam::volScalarField> To get your first approach running, this should be done: Code:
Foam::tmp<Foam::volScalarField> I hope I formulated it in a good way :) ... This will work: Code:
tmp<volScalarField> tnu = viscosityPtr_->nuHelium(); Code:
volScalarField nu = viscosityPtr_->nuHelium(); |
Hi Tobi,
Thank you very much for explanation, now it is clear for me. Unfortunately I still have an error with nuEff() function. This function is run in the line Code:
turbulence->divDevReff(U) Code:
Courant Number mean: 0 max: 0 |
There are too less information on what you changed. So it is not possible to give any advice, sorry.
|
Quote:
Code:
... Code:
nut = turbulence->nut() |
How did you define your object nut. Can you give the definition of that object? And where do you use nut afterwards?
|
nut definition in createFields.H:
Code:
volScalarField nut |
This cannot work because turbulence->nut() will return a tmp<> object which will be destoyed in your case :). So build your own field such as:
Code:
volScalarField nut Code:
Code:
tmp<volScalarField> tnut = turbulence->nut(); |
Quote:
Code:
Foam::tmp<Foam::volScalarField> |
Quote:
Code:
Foam::tmp<Foam::volScalarField> Code:
tmp<volScalarField> tnut = viscouseModel->calcNu(); Quote:
|
Any automatic object created within the body of a function can live untill the execution flow leaves the function. Then a destructor of the object is invoked rendering the object basically dead. A pointer to the automatic object can be incapsulated into a smart pointer object and returned from the function, but it will be useless anyway because the object it points to is dead. If you want an object to stay alive when the execution flow leaves the function you should create it with operator new as a dynamically allocated memory object.
|
Hmmm,.... actually without the new keyword it is not working at all based on the fact that the pointer has to point to an explicit allocated memory build by new. So you are right. Thanks for correcting me. For those who want to test it:
Code:
Foam::tmp<Foam::volScalarField> myCalc (const Foam::fvMesh& mesh) |
Hi, Tobias
Code:
//- Run-Time Error - object destroyed, reference point to some non-allocated memory Code:
const volScalarField& foo = myCalc(mesh)(); |
Hi,
yes it will give an runtime error. If one test the above code, the error appears. I was struggling about that in my openComfort library too because here I need access to the nut field which comes from the turbulence model. Right at the beginning I did this one: Code:
const volScalarField& nut = turbulence->nut(); Code:
const volScalarField nut = turbulence->nut() Code:
const tmp<volScalarField> tnut = turbulence->nut() |
Hopefully I could test it tomorrow and then get back to this thread.
|
I played around with the code and have to confirm that
Code:
const volScalarField& nut = turbulence->nut()(); |
Hmmm.... :/
Sure, it is obvious now. After the operator () we have access to the object and can take the reference. My way was wrong. Should think more before I reply. As always Sergei. Good point. Thanks for sharing. |
Quote:
Thank you guys for explanation all of these things and help. I solved my problem mentioned in #25. It was caused by the bed use of tmp object. I fixed the code according Zeppo solution as in the citation. Also I added this line according to Tobi: Code:
tmp<volScalarField> tnut = turbulence->nut(); |
All times are GMT -4. The time now is 03:54. |