CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Programming & Development

nuEff()()[patchI] and nuEff()

Register Blogs Community New Posts Updated Threads Search

Like Tree9Likes

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   November 5, 2017, 16:09
Default
  #21
Senior Member
 
Przemek
Join Date: Jun 2011
Posts: 249
Rep Power: 15
gaza is on a distinguished road
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.
__________________
best regards
pblasiak
gaza is offline   Reply With Quote

Old   November 5, 2017, 16:50
Default
  #22
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Tussenhausen
Posts: 2,708
Blog Entries: 6
Rep Power: 51
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
Okay, and how do you access the function? I mean, you should have something like that somewhere:

Code:
volScalarField foo = pointerToModel->nuHelium();
Actually I am interested in that line you should have somewhere (I guess in another form).
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   November 6, 2017, 02:35
Default
  #23
Senior Member
 
Przemek
Join Date: Jun 2011
Posts: 249
Rep Power: 15
gaza is on a distinguished road
yes it is inside singlePhaseTransportModel
Code:
 Foam::tmp<Foam::volScalarField>

 Foam::singlePhaseTransportModel::nu() const

 {

     return viscosityModelPtr_->nu();

 }
you can see it in doxygen. I changed only private to protected for viscosityModelPtr_.

Why are you asking?
__________________
best regards
pblasiak
gaza is offline   Reply With Quote

Old   November 6, 2017, 03:38
Default
  #24
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Tussenhausen
Posts: 2,708
Blog Entries: 6
Rep Power: 51
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
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>
Foam::viscosityModels::Helium::calcNu() 
{
    volScalarField nu
    (
        IOobject
        (
            "nuLocal",
            U_.time().timeName(),
            U_.db(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        eta_/rho_
    );
    return nu;
}
This code should be not working based on the fact that the object nu will be destroyed after the return statement. The returned tmp<> pointer points to a non-allocated memory address and thus you should get a run time error. However, your second example is working because you are returning the object returned by the max() function. The max() function will build a tmp<> object that will not be destroyed and thus, the object survives after returning.


To get your first approach running, this should be done:

Code:
Foam::tmp<Foam::volScalarField>
Foam::viscosityModels::Helium::calcNu() 
{
    tmp<volScalarField> nu
    (
        IOobject
        (
            "nuLocal",
            U_.time().timeName(),
            U_.db(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        eta_/rho_
    );
    return nu;
}
Here, you build the tmp object which knows how many pointers point on the object. If you return it, you have to store the returned object in a tmp<> object again, in order to keep the object alive. After the end of calcNu() is reached, the returned tmp<> object survives and you should not get an run time error.

I hope I formulated it in a good way ...

This will work:
Code:
tmp<volScalarField> tnu = viscosityPtr_->nuHelium();

//- Do other stuff
This will fail:
Code:
volScalarField nu = viscosityPtr_->nuHelium();
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   November 6, 2017, 07:14
Default
  #25
Senior Member
 
Przemek
Join Date: Jun 2011
Posts: 249
Rep Power: 15
gaza is on a distinguished road
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)
in the UEqn.H. I have this error now
Code:
Courant Number mean: 0 max: 0
deltaT = 9.999e-06
PIMPLE: iteration 1


--> FOAM FATAL ERROR: 
 Field<scalar> f1(14000), Field<scalar> f2(0) and Field<scalar> f3(14000)
    for operation f1 = f2 + f3

    From function void Foam::checkFields(const Foam::UList<T>&, const Foam::UList<Key>&, const Foam::UList<Type3>&, const char*) [with Type1 = double; Type2 = double; Type3 = double]
    in file /home/przemek/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/FieldM.H at line 75.

FOAM aborting

#0  Foam::error::printStack(Foam::Ostream&) at ~/OpenFOAM/OpenFOAM-v1606+/src/OSspecific/POSIX/printStack.C:218
#1  Foam::error::abort() at ~/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/error.C:246
#2  Foam::Ostream& Foam::operator<< <Foam::error>(Foam::Ostream&, Foam::errorManip<Foam::error>) at ~/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/errorManip.H:85 (discriminator 4)
#3  void Foam::checkFields<double, double, double>(Foam::UList<double> const&, Foam::UList<double> const&, Foam::UList<double> const&, char const*) at ~/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/FieldM.H:75
#4  void Foam::add<double, double>(Foam::Field<Foam::typeOfSum<double, double>::type>&, Foam::UList<double> const&, Foam::UList<double> const&) at ~/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/FieldFunctions.C:770
#5  void Foam::add<double, double, Foam::fvPatchField, Foam::volMesh>(Foam::GeometricField<Foam::typeOfSum<double, double>::type, Foam::fvPatchField, Foam::volMesh>&, Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> const&, Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> const&) at ~/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/GeometricFieldFunctions.C:961
#6  Foam::tmp<Foam::GeometricField<Foam::typeOfSum<double, double>::type, Foam::fvPatchField, Foam::volMesh> > Foam::operator+<double, double, Foam::fvPatchField, Foam::volMesh>(Foam::tmp<Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> > const&, Foam::tmp<Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> > const&) at ~/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/GeometricFieldFunctions.C:961 (discriminator 9)
#7  Foam::RASModel<Foam::IncompressibleTurbulenceModel<Foam::transportModel> >::nuEff() const at ~/OpenFOAM/OpenFOAM-v1606+/src/TurbulenceModels/incompressible/../turbulenceModels/lnInclude/RASModel.H:226 (discriminator 8)
#8  Foam::linearViscousStress<Foam::RASModel<Foam::IncompressibleTurbulenceModel<Foam::transportModel> > >::divDevRhoReff(Foam::GeometricField<Foam::Vector<double>, Foam::fvPatchField, Foam::volMesh>&) const at ~/OpenFOAM/OpenFOAM-v1606+/src/TurbulenceModels/incompressible/../turbulenceModels/lnInclude/linearViscousStress.C:101
#9  Foam::IncompressibleTurbulenceModel<Foam::transportModel>::divDevReff(Foam::GeometricField<Foam::Vector<double>, Foam::fvPatchField, Foam::volMesh>&) const at ~/OpenFOAM/OpenFOAM-v1606+/src/TurbulenceModels/incompressible/lnInclude/IncompressibleTurbulenceModel.C:116
#10  ? at ~/OpenFOAM/przemek-v1606+/applications/solvers/heatTransfer/buoyantBoussinesqSuperFluidPimpleFoam/UEqn.H:35
#11  __libc_start_main in "/lib/x86_64-linux-gnu/libc.so.6"
#12  ? at ??:?
Aborted (core dumped)
It results from that nuEff = nut() + nu() and nut() is size of zero and I do not know why.
__________________
best regards
pblasiak
gaza is offline   Reply With Quote

Old   November 6, 2017, 07:30
Default
  #26
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Tussenhausen
Posts: 2,708
Blog Entries: 6
Rep Power: 51
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
There are too less information on what you changed. So it is not possible to give any advice, sorry.
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   November 6, 2017, 07:46
Default
  #27
Senior Member
 
Przemek
Join Date: Jun 2011
Posts: 249
Rep Power: 15
gaza is on a distinguished road
Quote:
Originally Posted by gaza View Post
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)
in the UEqn.H. I have this error now
Code:
Courant Number mean: 0 max: 0
deltaT = 9.999e-06
PIMPLE: iteration 1


--> FOAM FATAL ERROR: 
 Field<scalar> f1(14000), Field<scalar> f2(0) and Field<scalar> f3(14000)
    for operation f1 = f2 + f3

    From function void Foam::checkFields(const Foam::UList<T>&, const Foam::UList<Key>&, const Foam::UList<Type3>&, const char*) [with Type1 = double; Type2 = double; Type3 = double]
    in file /home/przemek/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/FieldM.H at line 75.

FOAM aborting

#0  Foam::error::printStack(Foam::Ostream&) at ~/OpenFOAM/OpenFOAM-v1606+/src/OSspecific/POSIX/printStack.C:218
#1  Foam::error::abort() at ~/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/error.C:246
#2  Foam::Ostream& Foam::operator<< <Foam::error>(Foam::Ostream&, Foam::errorManip<Foam::error>) at ~/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/errorManip.H:85 (discriminator 4)
#3  void Foam::checkFields<double, double, double>(Foam::UList<double> const&, Foam::UList<double> const&, Foam::UList<double> const&, char const*) at ~/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/FieldM.H:75
#4  void Foam::add<double, double>(Foam::Field<Foam::typeOfSum<double, double>::type>&, Foam::UList<double> const&, Foam::UList<double> const&) at ~/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/FieldFunctions.C:770
#5  void Foam::add<double, double, Foam::fvPatchField, Foam::volMesh>(Foam::GeometricField<Foam::typeOfSum<double, double>::type, Foam::fvPatchField, Foam::volMesh>&, Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> const&, Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> const&) at ~/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/GeometricFieldFunctions.C:961
#6  Foam::tmp<Foam::GeometricField<Foam::typeOfSum<double, double>::type, Foam::fvPatchField, Foam::volMesh> > Foam::operator+<double, double, Foam::fvPatchField, Foam::volMesh>(Foam::tmp<Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> > const&, Foam::tmp<Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> > const&) at ~/OpenFOAM/OpenFOAM-v1606+/src/OpenFOAM/lnInclude/GeometricFieldFunctions.C:961 (discriminator 9)
#7  Foam::RASModel<Foam::IncompressibleTurbulenceModel<Foam::transportModel> >::nuEff() const at ~/OpenFOAM/OpenFOAM-v1606+/src/TurbulenceModels/incompressible/../turbulenceModels/lnInclude/RASModel.H:226 (discriminator 8)
#8  Foam::linearViscousStress<Foam::RASModel<Foam::IncompressibleTurbulenceModel<Foam::transportModel> > >::divDevRhoReff(Foam::GeometricField<Foam::Vector<double>, Foam::fvPatchField, Foam::volMesh>&) const at ~/OpenFOAM/OpenFOAM-v1606+/src/TurbulenceModels/incompressible/../turbulenceModels/lnInclude/linearViscousStress.C:101
#9  Foam::IncompressibleTurbulenceModel<Foam::transportModel>::divDevReff(Foam::GeometricField<Foam::Vector<double>, Foam::fvPatchField, Foam::volMesh>&) const at ~/OpenFOAM/OpenFOAM-v1606+/src/TurbulenceModels/incompressible/lnInclude/IncompressibleTurbulenceModel.C:116
#10  ? at ~/OpenFOAM/przemek-v1606+/applications/solvers/heatTransfer/buoyantBoussinesqSuperFluidPimpleFoam/UEqn.H:35
#11  __libc_start_main in "/lib/x86_64-linux-gnu/libc.so.6"
#12  ? at ??:?
Aborted (core dumped)
It results from that nuEff = nut() + nu() and nut() is size of zero and I do not know why.
Ok I found the origin of the error. I had the code in UEqn.H
Code:
...
    nut = turbulence->nut();

    tmp<fvVectorMatrix> tUEqn 
    ( 
         fvm::ddt(U) + fvm::div(phi, U) 
      + MRF.DDt(U) 
      + turbulence->divDevReff(U)     
     == 
         fvOptions(U) 
     );
If I comment the line
Code:
nut = turbulence->nut()
everything works well, but I do not know why???
__________________
best regards
pblasiak
gaza is offline   Reply With Quote

Old   November 6, 2017, 07:49
Default
  #28
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Tussenhausen
Posts: 2,708
Blog Entries: 6
Rep Power: 51
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
How did you define your object nut. Can you give the definition of that object? And where do you use nut afterwards?
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   November 6, 2017, 08:01
Default
  #29
Senior Member
 
Przemek
Join Date: Jun 2011
Posts: 249
Rep Power: 15
gaza is on a distinguished road
nut definition in createFields.H:

Code:
 volScalarField nut 
( 
     IOobject 
     ( 
         "nut", 
        runTime.timeName(), 
         mesh, 
         IOobject::NO_READ, 
         IOobject::NO_WRITE 
     ), 
     turbulence->nut()  
);
and I do not use it before line nut = turbulence->nut();
__________________
best regards
pblasiak
gaza is offline   Reply With Quote

Old   November 6, 2017, 08:08
Default
  #30
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Tussenhausen
Posts: 2,708
Blog Entries: 6
Rep Power: 51
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
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 
( 
     IOobject 
     ( 
         "nut", 
        runTime.timeName(), 
         mesh, 
         IOobject::NO_READ, 
         IOobject::NO_WRITE 
     ), 
     mesh,
     dimensionedScalar("nut", dimensionSet(...), value(0))
);
then you should get access to the field such as:
Code:
// Keep tmp alive
tmp<volScalarField> tnut = turbulence->nut();

// Get reference to nut object
volScalarField& nutIF = nut;

// Set nut to be tnut from turbulence model
nutIF = tnut();
Or simply use:
Code:
tmp<volScalarField> tnut = turbulence->nut();
without creating a volScalarField in the createFields.H
gaza likes this.
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   November 6, 2017, 16:44
Default
  #31
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
Quote:
Originally Posted by Tobi View Post
To get your first approach running, this should be done:

Code:
Foam::tmp<Foam::volScalarField>
Foam::viscosityModels::Helium::calcNu() 
{
    tmp<volScalarField> nu
    (
        IOobject
        (
            "nuLocal",
            U_.time().timeName(),
            U_.db(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        eta_/rho_
    );
    return nu;
}
This should be corrected a little bit:
Code:
Foam::tmp<Foam::volScalarField>
Foam::viscosityModels::Helium::calcNu() 
{
    tmp<volScalarField> nu
    (
        new volScalarField
        (
            IOobject
            (
                "nuLocal",
                U_.time().timeName(),
                U_.db(),
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            eta_/rho_
        );
    )
    return nu;
}
To my understanding it is essential that the object of volScalarField type is to be created in dynamic memory (on the heap) with operator new. If so, tmp can store a pointer to some place in dynamic memory which will stay untouched while tmp is returned from calcNu. On the other hand, when you initialize tmp with a pointer/reference to an automatic object (i.e., in simple words, you don't use operator new to create an object) tmp stores a pointer to a place in automatic memory (on the stack) which will be "erased" as soon as you return from calcNu and it yields undefinite behaviour.
Tobi and gaza like this.
Zeppo is offline   Reply With Quote

Old   November 6, 2017, 18:10
Default
  #32
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Tussenhausen
Posts: 2,708
Blog Entries: 6
Rep Power: 51
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
Quote:
On the other hand, when you initialize tmp with a pointer/reference to an automatic object (i.e., in simple words, you don't use operator new to create an object) tmp stores a pointer to a place in automatic memory (on the stack) which will be "erased" as soon as you return from calcNu and it yields undefinite behaviour.
Is is like that? I don't think so because the tmp<> class knows how much pointer points to the object. Therefore, if one returns the object such as:
Code:
Foam::tmp<Foam::volScalarField>
Foam::viscosityModels::Helium::calcNu() 
{
    tmp<volScalarField> nu
    (
        IOobject
        (
            "nuLocal",
            U_.time().timeName(),
            U_.db(),
            IOobject::NO_READ,
            IOobject::NO_WRITE
        ),
        eta_/rho_
    );
    return nu;
}
while taking the returned pointer such as:
Code:
tmp<volScalarField> tnut = viscouseModel->calcNu();
The object should be still alive, even if we leave the calcNu() function because a pointer still points onto the object. But out of the box I cannot proof that. Bruno told me once the following:

Quote:
"tmp" is a pointer wrapper class that handles reference counting depending on the operator that is used.

You should see several examples in OpenFOAM, such as:
const tmp<volScalarField> tnuEff = turbulence->nuEff();
const volScalarField& nuEff = tnuEff();
"tnuEff" is a self-destructing capsule that stores a pointer (it's a something something "RAII" trick in C++). When the destructor of "tmp" is called, it will take the pointer inside with it.

If you do this:
turbulence->nuEff()()
It destroys its content after self-destruction, namely when the destructor is called for the object that was returned by "return tmp<volScalarField> nuEff", because no one is holding it after this line of code is processed.

That's why you must keep a live object of "tmp" inside the current method/function.


The "autoptr" class that sometimes is used in C++ for managing pointers does this as well.
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   November 7, 2017, 16:12
Default
  #33
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
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.
Zeppo is offline   Reply With Quote

Old   November 7, 2017, 17:27
Default
  #34
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Tussenhausen
Posts: 2,708
Blog Entries: 6
Rep Power: 51
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
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)               
{                                                                               
    tmp<volScalarField> T                                                       
    (                                                                           
        new volScalarField                                                      
        (                                                                       
            IOobject                                                            
            (                                                                   
                "T",                                                            
                mesh.time().timeName(),                                         
                mesh,                                                           
                IOobject::MUST_READ,                                            
                IOobject::AUTO_WRITE                                            
            ),                                                                  
            mesh                                                                
        )                                                                       
    );                                                                          
                                                                                
    return T;                                                                   
}                                                                               
                                                                                
int main(int argc, char *argv[])                                                
{                                                                               
    #include "setRootCase.H"                                                    
    #include "createTime.H"                                                     
    #include "createMesh.H"                                                     
         
    //- Working - keeping object alive                                                                   
    tmp<volScalarField> re = myCalc(mesh);                                                                                                         
    Info<< re() << endl;                

    //- Run-Time Error - object destroyed, reference point to some non-allocated memory
    const volScalarField& foo = myCalc(mesh);                                   
    Info<< foo << endl;   
    
                                        
                                                                                
                                                                                
    Info<< "End\n" << endl;                                                     
                                                                                
    return 0;                                                                   
}
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   November 8, 2017, 16:56
Default
  #35
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
Hi, Tobias
Code:
//- Run-Time Error - object destroyed, reference point to some non-allocated memory
    const volScalarField& foo = myCalc(mesh);                                   
    Info<< foo << endl;
Are you sure this piece of code issues an error? I didn't try it personally, but I believe it should be ok. myCalc returns a temporary object which is assigned to a const reference foo. And c++ rules make it possible: a constant reference can be "initialized" with a temporary object. The temporary object doesn't die right away, it's lifetime prolongates up to the constant reference lifetime. And they both will live untill the execution flow leaves the scope where the constant reference was defined. This code might not work for one reason though: myCalc returns tmp and foo expects volScalarField, I am not sure tmp can "converts" to volScalarField implicitly. If you do the conversion explicitly (with operator()) it should work like a breeze:
Code:
const volScalarField& foo =  myCalc(mesh)();
Zeppo is offline   Reply With Quote

Old   November 8, 2017, 17:01
Default
  #36
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Tussenhausen
Posts: 2,708
Blog Entries: 6
Rep Power: 51
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
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();
However, this code failed always. Therefore, I replaced it with a copy operator which worked (obviously):
Code:
const volScalarField nut = turbulence->nut()
I was not happy about copying the object and asked Bruno. He gave me the explanation, that we have to keep a object of the tmp<> class alive by doing that:
Code:
const tmp<volScalarField> tnut = turbulence->nut()
Otherwise the object returned by the nut() function will be destroyed. You might be right that it will work with smart pointers like the auto_ptr in c++ but with the FOAM tmp<> class actually not (tested it).
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   November 8, 2017, 17:09
Default
  #37
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
Hopefully I could test it tomorrow and then get back to this thread.
Zeppo is offline   Reply With Quote

Old   November 9, 2017, 16:35
Default
  #38
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
I played around with the code and have to confirm that
Code:
const volScalarField& nut = turbulence->nut()();
fails at runtime. You have to use a pair of round brackets at the end of this expression to obtain (a reference to) volScalarField out of tmp. Otherwise it won't even compile let alone run.
Tobi likes this.
Zeppo is offline   Reply With Quote

Old   November 9, 2017, 18:47
Default
  #39
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Tussenhausen
Posts: 2,708
Blog Entries: 6
Rep Power: 51
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
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.
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   November 11, 2017, 08:45
Default
  #40
Senior Member
 
Przemek
Join Date: Jun 2011
Posts: 249
Rep Power: 15
gaza is on a distinguished road
Quote:
Originally Posted by Zeppo View Post
This should be corrected a little bit:
Code:
Foam::tmp<Foam::volScalarField>
Foam::viscosityModels::Helium::calcNu() 
{
    tmp<volScalarField> nu
    (
        new volScalarField
        (
            IOobject
            (
                "nuLocal",
                U_.time().timeName(),
                U_.db(),
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            eta_/rho_
        );
    )
    return nu;
}
To my understanding it is essential that the object of volScalarField type is to be created in dynamic memory (on the heap) with operator new. If so, tmp can store a pointer to some place in dynamic memory which will stay untouched while tmp is returned from calcNu. On the other hand, when you initialize tmp with a pointer/reference to an automatic object (i.e., in simple words, you don't use operator new to create an object) tmp stores a pointer to a place in automatic memory (on the stack) which will be "erased" as soon as you return from calcNu and it yields undefinite behaviour.
Hi Tobi and Zeppo
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();
alphaEff = turbulence->nu() + tnut();
Thank's for sharing
__________________
best regards
pblasiak
gaza is offline   Reply With Quote

Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Calculating divDevReff jposunz OpenFOAM Running, Solving & CFD 82 June 12, 2022 14:01
Add new nuEff() law to simpleFoam T.D. OpenFOAM Running, Solving & CFD 2 July 16, 2015 07:27
Calculate and display eddy viscosity ceyrows OpenFOAM Running, Solving & CFD 4 February 16, 2009 12:57


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