CFD Online Discussion Forums

CFD Online Discussion Forums (http://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (http://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   objectRegistry::lookupObject<scalar> (http://www.cfd-online.com/Forums/openfoam-programming-development/88823-objectregistry-lookupobject-scalar.html)

brent_craven May 26, 2011 20:19

objectRegistry::lookupObject<scalar>
 
Hello all,

In boundary conditions/fvPatchFields it is quite common to "lookup" required dictionaries, variables, etc. via something like:

const volScalarField& someVariable = this->db().objectRegistry::lookupObject<volScalarField> ("someVariable");

or for a dictionary….

const dictionary& someDictionary = db().time().lookupObject<IOdictionary>("someDictio nary");
const scalar& someParameter = readScalar(someDictionary.lookup("someParameter")) ;


This works because each of the variables and dictionaries are instantiated as "IOobjects," which places them into the "objectRegistry" via something like:

IOdictionary someDictionary
(
IOobject
(
"someDictionary",
runTime.constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);


So, here is my problem: within my custom boundary condition I need to "lookup" a "scalar" variable that exists within the scope of the main solver. But, I cannot figure out the following:

1. How to instantiate a "scalar" variable as an IOobject such that it is placed within the objectRegistry, permitting me to look it up
2. Within the boundary condition, how does one "lookup" a scalar variable from the objectRegistry? objectRegistry::lookupObject<scalar> does not seem to work


Has anyone done this?

Thanks!

Brent

marupio May 26, 2011 21:59

A scalar is not an IOobject, and cannot be directly looked up.

Where are you getting the scalar from? Is it a setting specified by the user? If so, it exists in a dictionary somewhere... or is it hard-coded?

As a work-around, you could create a dictionary at the top level, and add the scalar to it, then look-up the dictionary.

brent_craven May 26, 2011 22:53

Thanks, David. I like your workaround.

I briefly thought of this. The only complication to adding it to a top-level dictionary is that the scalar value changes every iteration throughout the simulation.

But, now that I think of it more - the dictionary is be looked up in memory and not from file. So, every time the scalar value changes the new value can be looked up via the dictionary that is stored in memory. At least, that's how I think it should work. I'll give it a shot.

Thanks for the advice.

alberto May 27, 2011 01:56

Hi,

let's consider a general example to search in a dictionary. :-)

Your solver uses the "transportProperties" dictionary, which contains a subdictionary, called "mySubDict". This sub-dictionary contains your dimensioned scalar, named "myScalar".

In the BC, you can recover "myScalar" as follows:

Code:

// Extract the dictionary from the database
const dictionary& transportProperties = db().lookupObject<IOdictionary>
(
  "transportProperties"
);

// Exctract subdictionary from the main dictionary
dictionary mySubDict
(
    transportProperties.subDict("mySubDict")
);

// Extracting scalar value
dimensionedScalar myScalar(mySubDict.lookup("myScalar"));

Of course this works also if you do not have sub-dictionaries, using the "lookup" method directly on the main dictionary.

Note: this value is not updated at runtime. Since it seems you need that, if the value is computed from fields, the easy way is to compute it on the patch looking up for the fields.

Best,

brent_craven May 27, 2011 09:20

That's good to know that dictionary entries are not updated at runtime.

I might try calculating it on the patch, although this will be difficult as well since the value depends on previous iterations and a number of field variables.

One other thought I had was to try the templated IOField class with Type "scalar", which will allow me to lookup this IOField<scalar> value from the objectRegistry within the boundary condition.

Thanks for all the input.


-Brent

marupio May 27, 2011 10:51

It's true that read-only dictionaries are not updated at runtime... but you could make a dictionary, and update it at every timestep. Let's say you derive the value of the scalar in the top level... simply write that value to the dictionary immediately afterward. Make the dictionary a no-read / never write, and it will exist only in memory - essentially a workaround for looking up a scalar.

brent_craven May 27, 2011 13:58

Ahh - a good suggestion. Thanks, David.

Do you know off the top of your head how to update/write to the dictionary "on demand"?


Thanks again!

Brent

marupio May 27, 2011 14:51

May require some changes while debugging, but here's the essence:

Code:

// in createFields.H
IOdictionary scalarDict
(
    IOobject
    (
        "scalarDict",
        runTime.constant(),
        mesh,
        IOobject::NO_READ,
        IOobject::NO_WRITE
    )
);

// In runTime loop:
scalarDict.set("nameOfScalar", valueOfScalar);

// and you're done

I hope that helps!

brent_craven May 27, 2011 15:03

Beautiful. Thanks!

It was the .set() member function that I was missing.

Thanks again.

Brent

nimasam June 29, 2011 09:17

hi
i encounter the same problem! any solution to update a value in boundary from main solver in runtime?
if yes, whats the procedure ?

marupio June 29, 2011 09:36

Do you want the main solver to change the boundary value? Or do you want the boundary to update itself with a value calculated in the main solver?

The first one is easy - you can access the boundary field of a geometricField. I think it's something like:

U.boundaryField()[patch number][face number]

I'm not sure why you'd want to do this... you shouldn't tie a specific boundary condition to a solver.

The second one is what we were discussing above with the dictionary look-up work-around.

nimasam June 29, 2011 09:52

the second one ;)
i have fan boundary condition, in fan boundary condition we should assign a scalar value "f" in BC, which shows jump value between two couple patches. in my case, f changes in each time step! and im calculating f in my solver
now i like to update the value of f in BC by reading this value from solver

brent_craven June 29, 2011 10:39

Yes. The methodology discussed by David above (http://www.cfd-online.com/Forums/ope...tml#post309556) worked well for me:

1. Declare the scalar as an IOobject
2. Calculate the scalar in your solver
3. Update the new scalar value with: scalarDict.set("nameOfScalar", valueOfScalar);
4. Access the new scalar value in your BC via a "db().lookupObject<IOdictionary>" (e.g., http://www.cfd-online.com/Forums/ope...tml#post309443)

marupio June 29, 2011 10:41

Hi nima,

I'd suggest you use the IOdictionary work-around we were discussing above.

1. In your solver, implement the suggestions I posted earlier:

Quote:

Originally Posted by marupio (Post 309556)
May require some changes while debugging, but here's the essence:

Code:

// in createFields.H
IOdictionary scalarDict
(
    IOobject
    (
        "scalarDict",
        runTime.constant(),
        mesh,
        IOobject::NO_READ,
        IOobject::NO_WRITE
    )
);

// In runTime loop:
scalarDict.set("nameOfScalar", valueOfScalar);

// and you're done

I hope that helps!

Your "nameOfScalar" will be "f", and the value will be what you calculated for f. Then in the boundary condition update function, use lookupObject<IOdictionary>("scalarDict") or something like that. Then you can read the value from the dictionary with readScalar(scalarDict.lookup("f")).

nimasam June 29, 2011 11:20

thank you both of you ;), i found that there is a bug in openFOAM1.6 and it cant update the value in dict
http://www.cfd-online.com/Forums/ope...-updating.html

nimasam June 30, 2011 04:11

sorry i followed above procedure but! i encounter bellow error:
1) if i use ( no read , no write ) , when im going to read in boundary condition, it says:
keyword f is undefined in dictionary ".../constant/scalarDict"

2) if i use other options! it cant update the value in dictionary and it just reads the fixed value i wrote in dict!

olesen July 1, 2011 06:18

Quote:

Originally Posted by nimasam (Post 314176)
sorry i followed above procedure but! i encounter bellow error:
1) if i use ( no read , no write ) , when im going to read in boundary condition, it says:
keyword f is undefined in dictionary ".../constant/scalarDict"

2) if i use other options! it cant update the value in dictionary and it just reads the fixed value i wrote in dict!


If you examine the code, you'll see that there are *lots* of places that use the lookupObject to access global information. The object that it finds does not have to be a dictionary. You can simply define your own class, give it a lookup name and go from there. This is probably what you want anyhow.

nimasam July 1, 2011 07:25

thank oselen
could you please, give me step by step procedure how i can assing a scalar value an IOobject and i can look at with lookupObject ?

olesen July 1, 2011 07:51

Quote:

Originally Posted by nimasam (Post 314388)
thank oselen
could you please, give me step by step procedure how i can assing a scalar value an IOobject and i can look at with lookupObject ?

Here are the docs for IOobject:
http://foam.sourceforge.net/docs/cpp....html#_details
You should have no problem finding plenty of examples in the source code.
I would suspect that you'd want the default parameters (ie, NO_READ, NO_WRITE and register).

nimasam July 1, 2011 13:52

i used following steps:

1) add to main solver
#include "scalarIOList.H" //add

2) add to creatFields.H

scalarIOList jump
(
IOobject(
"jump",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
label(1.0));

3) update

jump[0] = myvalue;

4) in boundary condition i add :

const scalarIOList& jump =
db().lookupObject<scalarIOList>("jump");

but i faced following strange!!!!! error

lookup of jump from objectRegistry region0 successful
but it is not a scalarList, it is a scalarList ???????????

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


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