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/)
-   -   Introducing the IOReferencer (https://www.cfd-online.com/Forums/openfoam-programming-development/91504-introducing-ioreferencer.html)

marupio August 12, 2011 14:54

Introducing the IOReferencer
 
Hi Foamers,

I've thrown together a simple piece of code that allows you to look up non-IOobjects from the objectRegistry.

It's fairly straightforward:

  • The installation involves copying two files (no compiling);
  • The example of how to use it is in the header description.

Download it from:

http://openfoam-extend.svn.sourcefor...ject/?view=tar

The wiki page is currently down, but once it's up again, I'll upload the more detailed instructions to:

http://openfoamwiki.net/index.php/Contrib_IOReferencer

brent_craven August 12, 2011 15:27

Introducing the IOReferencer
 
Very nice! Thanks for the contribution.

marupio August 13, 2011 11:38

Wiki instructions uploaded.

winden December 7, 2012 11:33

Hi.

Thanks for a great contribution. I'm having some trouble and I was wondering if it is the IOReferencer or if I have done something else that is stupid :)

I would like to keep a pointer to a class (which class gets decided in the solver based on a dictionary) in the registry to access its member functions in other parts of the code.

In the solver I have:

Code:

autoPtr<myClass> pPtr = myClass::New(dict);


IOReferencer< autoPtr<myClass> > myObject
    (
        IOobject
            (
        "pControl",
        runTime.constant(),
        mesh,
        IOobject::NO_READ,
                IOobject::NO_WRITE
        ),
    pPtr
    );

And I access and use it elsewhere as:
Code:

pC = db.lookupObject<IOReferencer<autoPtr<myClass> > >("pControl")();

pForce_ = (pC->myMemberFunction(*this,deltaT));

I'm getting some weird behaviour from this. Sometimes the lookup works fine and the pC->myMemberFunction works fine but when the solver reaches a timestep where the write command is executed, it crashes. On the other hand, if I recompile the same code and run it again I sometimes instead get the following error in the first timestep:
Code:

--> FOAM FATAL ERROR:

    lookup of pControl from objectRegistry region0 successful
    but it is not a regIOobject, it is a regIOobject

    From function objectRegistry::lookupObject<Type>(const word&) const
    in file /opt/openfoam171/src/OpenFOAM/lnInclude/objectRegistryTemplates.C at line 120.

FOAM aborting

At first I didn't think it would work at all to send an autoPtr like this but I was surprised to see that it actually worked only to eventually be disappointed that it doesn't seem to be a stable way of doing it.

//Björn

marupio December 7, 2012 11:47

I've encountered this before... it's ugly. That last error you get occurs during an object registry lookup when the type name is correct, but the dynamic_cast still fails. This is one of those compiler issues. If I recall, the cast fails because the object is not the correct size. I can only guess that this occurs when "myClass" is complex. Is it templated, by chance?

The IOReferencer was mostly designed for primitives. If you have a complex custom class, it may be easier to just make it an IOobject, if you can.

However, you may find that it still fails the object lookup even without IOReferencer... in which case I'd suggest trying to change the class structure.

winden December 7, 2012 12:08

Hi. Thanks for the quick reply. myClass is indeed complex. It is a base class for selecting different propeller modelling techniques. (I modified it from the way constraints are selected for sixdofrigidbodymotion and I can't say I fully understand what all of it does.)

Hopefully, I can find another solution. There is always the possibility to change the structure so that I have direct access to the class where I wanted to use it. However that would mean having to create a lot of custom solutions for many of the base classes that lie above the class where I want to access it so I was hoping to avoid that. Anyway, thanks for letting me know what the problem was.

//Björn

andyru September 3, 2014 12:54

why not using scalarIOField?
 
Hi,

maybe too late but why not using for example in main solver:
Code:

scalarIOField test
(
        IOobject
        (
            "test",
        runTime.constant(),
        mesh,
        IOobject::NO_READ,
        IOobject::NO_WRITE
        ),
        <sizeOfWishedScalarList<
);
test = <valuesToBePutIntotest>;

then in boundary condition, for instance:
Code:

scalarIOField test =
        const_cast<scalarIOField&>
        (
        db().lookupObject<scalarIOField>("test")
        );

Works also for vectorIOField.

If you want to get only one scalar, then you have to use scalarIOField with size one, since there is no scalarIO.H...

I hope this helps!

Andy

suunto July 28, 2016 10:07

Hello,

I am trying to use the IOReferencer to pass a vector from a custom fvOptions to a custom dynamicFvMesh class. Is this possible? When executing a solver, I get the following error:

Code:

--> FOAM FATAL ERROR:

    request for regIOobject testVector from objectRegistry region0 failed
    available objects of type regIOobject are
0()

    From function objectRegistry::lookupObject<Type>(const word&) const
    in file /home/OpenFOAM/OpenFOAM-2.4.x/src/OpenFOAM/lnInclude/objectRegistryTemplates.C at line 198.

FOAM aborting

In my fvOptions source I added:
Code:

    vector testVector = vector(1, 2, 3);

    IOReferencer<vector> testVectorRef
    (
        IOobject
        (
            "testVector",
            mesh_.time().timeName(), //can be anything
            mesh_,                            //can be anything
            IOobject::NO_READ,      //must be NO_READ
            IOobject::NO_WRITE      //must be NO_WRITE
        ),
        testVector
    );

and then in the dynamicFvMesh class:
Code:

const fvMesh& mesh = time().db().parent().lookupObject<fvMesh>("region0");
const vector& Tout = mesh.lookupObject<IOReferencer<vector> >
(
    "testVector"
)();

Is this a scope issue or am I using the code incorrectly? Thanks for any hints.

marupio July 28, 2016 10:46

It looks okay. Probably a scope issue. Does the testVector thing go out of scope? If it does, you can make it a member variable <-- probably the best option. Otherwise, try adding testVector.store(); just before the end of the function... but then I'm not sure how it will behave if you do this on the second iteration.

marupio July 28, 2016 10:46

Also note that IOReferencer was incorporated by the community into foam-extend, and has since been improved there.

suunto July 28, 2016 11:32

Hi David,

The compiler doesn't complain about going out of scope. I tried adding testVector.store(); at the end of the fvOptions source but store() does not appear to be a member function of a vector:
Code:

error: ‘Foam::vector’ has no member named ‘store’
I will also look into the foam-extend implementation. Thanks for your help!

suunto July 28, 2016 15:54

I've looked into using the foam-extend version of the IOReferencer and I get the following error upon compilation:

Code:

test.C:100:5: error: no matching function for call to ‘Foam::IOReferencer<Foam::Vector<double> >::IOReferencer(Foam::IOobject, Foam::vector&)’
test.C:100:5: note: candidates are:
/home/OpenFOAM/OpenFOAM-2.4.x/src/OpenFOAM/lnInclude/IOReferencer.C:53:1: note: Foam::IOReferencer<Type>::IOReferencer(const Foam::IOobject&, Type*) [with Type = Foam::Vector<double>, Foam::IOobject = Foam::IOobject]
/home/OpenFOAM/OpenFOAM-2.4.x/src/OpenFOAM/lnInclude/IOReferencer.C:53:1: note:  no known conversion for argument 2 from ‘Foam::vector {aka Foam::Vector<double>}’ to ‘Foam::Vector<double>*’
/home/OpenFOAM/OpenFOAM-2.4.x/src/OpenFOAM/lnInclude/IOReferencer.C:31:1: note: Foam::IOReferencer<Type>::IOReferencer(const Foam::IOobject&) [with Type = Foam::Vector<double>, Foam::IOobject = Foam::IOobject]
/home/OpenFOAM/OpenFOAM-2.4.x/src/OpenFOAM/lnInclude/IOReferencer.C:31:1: note:  candidate expects 1 argument, 2 provided
/home/OpenFOAM/OpenFOAM-2.4.x/src/OpenFOAM/lnInclude/IOReferencer.H:85:7: note: Foam::IOReferencer<Foam::Vector<double> >::IOReferencer(const Foam::IOReferencer<Foam::Vector<double> >&)
/home/OpenFOAM/OpenFOAM-2.4.x/src/OpenFOAM/lnInclude/IOReferencer.H:85:7: note:  candidate expects 1 argument, 2 provided

Sorry for a dumb question but is this related to the difference between foam-extend and OpenFOAM or do I simply need to change the syntax of the IOReferencer object? I am not really sure which 2 arguments are the offenders in this case.


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