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

objectRegistry::lookupObject<scalar>

Register Blogs Members List Search Today's Posts Mark Forums Read

Like Tree2Likes

Reply
 
LinkBack Thread Tools Display Modes
Old   May 26, 2011, 20:19
Default objectRegistry::lookupObject<scalar>
  #1
New Member
 
Brent Craven
Join Date: Mar 2009
Location: University Park, PA, USA
Posts: 21
Rep Power: 7
brent_craven is on a distinguished road
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
brent_craven is offline   Reply With Quote

Old   May 26, 2011, 21:59
Default
  #2
Senior Member
 
David Gaden
Join Date: Apr 2009
Location: Winnipeg, Canada
Posts: 393
Rep Power: 10
marupio is on a distinguished road
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.
marupio is offline   Reply With Quote

Old   May 26, 2011, 22:53
Default
  #3
New Member
 
Brent Craven
Join Date: Mar 2009
Location: University Park, PA, USA
Posts: 21
Rep Power: 7
brent_craven is on a distinguished road
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.
brent_craven is offline   Reply With Quote

Old   May 27, 2011, 01:56
Default
  #4
Senior Member
 
Alberto Passalacqua
Join Date: Mar 2009
Location: Ames, Iowa, United States
Posts: 1,880
Rep Power: 25
alberto will become famous soon enoughalberto will become famous soon enough
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,
__________________
Alberto

GeekoCFD - A free distribution based on openSUSE 64 bit with CFD tools, including OpenFOAM. Available as live DVD/USB, hard drive image and virtual image.
GeekoCFD 32bit - The 32bit edition of GeekoCFD.
GeekoCFD text mode - A smaller version of GeekoCFD, text-mode only, with only OpenFOAM. Available in a variety of virtual formats.

Last edited by alberto; May 27, 2011 at 02:38. Reason: Added note
alberto is offline   Reply With Quote

Old   May 27, 2011, 09:20
Default
  #5
New Member
 
Brent Craven
Join Date: Mar 2009
Location: University Park, PA, USA
Posts: 21
Rep Power: 7
brent_craven is on a distinguished road
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
brent_craven is offline   Reply With Quote

Old   May 27, 2011, 10:51
Default
  #6
Senior Member
 
David Gaden
Join Date: Apr 2009
Location: Winnipeg, Canada
Posts: 393
Rep Power: 10
marupio is on a distinguished road
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.
marupio is offline   Reply With Quote

Old   May 27, 2011, 13:58
Default
  #7
New Member
 
Brent Craven
Join Date: Mar 2009
Location: University Park, PA, USA
Posts: 21
Rep Power: 7
brent_craven is on a distinguished road
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
brent_craven is offline   Reply With Quote

Old   May 27, 2011, 14:51
Default
  #8
Senior Member
 
David Gaden
Join Date: Apr 2009
Location: Winnipeg, Canada
Posts: 393
Rep Power: 10
marupio is on a distinguished road
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!
marupio is offline   Reply With Quote

Old   May 27, 2011, 15:03
Default
  #9
New Member
 
Brent Craven
Join Date: Mar 2009
Location: University Park, PA, USA
Posts: 21
Rep Power: 7
brent_craven is on a distinguished road
Beautiful. Thanks!

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

Thanks again.

Brent
brent_craven is offline   Reply With Quote

Old   June 29, 2011, 09:17
Default
  #10
Senior Member
 
Nima Sam
Join Date: Sep 2009
Location: Tehran, Iran
Posts: 1,066
Blog Entries: 1
Rep Power: 14
nimasam is on a distinguished road
Send a message via Yahoo to nimasam
hi
i encounter the same problem! any solution to update a value in boundary from main solver in runtime?
if yes, whats the procedure ?
nimasam is offline   Reply With Quote

Old   June 29, 2011, 09:36
Default
  #11
Senior Member
 
David Gaden
Join Date: Apr 2009
Location: Winnipeg, Canada
Posts: 393
Rep Power: 10
marupio is on a distinguished road
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.
marupio is offline   Reply With Quote

Old   June 29, 2011, 09:52
Default
  #12
Senior Member
 
Nima Sam
Join Date: Sep 2009
Location: Tehran, Iran
Posts: 1,066
Blog Entries: 1
Rep Power: 14
nimasam is on a distinguished road
Send a message via Yahoo to nimasam
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
nimasam is offline   Reply With Quote

Old   June 29, 2011, 10:39
Default
  #13
New Member
 
Brent Craven
Join Date: Mar 2009
Location: University Park, PA, USA
Posts: 21
Rep Power: 7
brent_craven is on a distinguished road
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)
brent_craven is offline   Reply With Quote

Old   June 29, 2011, 10:41
Default
  #14
Senior Member
 
David Gaden
Join Date: Apr 2009
Location: Winnipeg, Canada
Posts: 393
Rep Power: 10
marupio is on a distinguished road
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 View Post
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")).
ganeshv likes this.
marupio is offline   Reply With Quote

Old   June 29, 2011, 11:20
Default
  #15
Senior Member
 
Nima Sam
Join Date: Sep 2009
Location: Tehran, Iran
Posts: 1,066
Blog Entries: 1
Rep Power: 14
nimasam is on a distinguished road
Send a message via Yahoo to nimasam
thank you both of you , i found that there is a bug in openFOAM1.6 and it cant update the value in dict
Dictionary Updating
nimasam is offline   Reply With Quote

Old   June 30, 2011, 04:11
Default
  #16
Senior Member
 
Nima Sam
Join Date: Sep 2009
Location: Tehran, Iran
Posts: 1,066
Blog Entries: 1
Rep Power: 14
nimasam is on a distinguished road
Send a message via Yahoo to nimasam
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!
nimasam is offline   Reply With Quote

Old   July 1, 2011, 06:18
Default
  #17
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: http://olesenm.github.io/
Posts: 774
Rep Power: 17
olesen will become famous soon enough
Quote:
Originally Posted by nimasam View Post
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.
olesen is offline   Reply With Quote

Old   July 1, 2011, 07:25
Default
  #18
Senior Member
 
Nima Sam
Join Date: Sep 2009
Location: Tehran, Iran
Posts: 1,066
Blog Entries: 1
Rep Power: 14
nimasam is on a distinguished road
Send a message via Yahoo to nimasam
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 ?
nimasam is offline   Reply With Quote

Old   July 1, 2011, 07:51
Default
  #19
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: http://olesenm.github.io/
Posts: 774
Rep Power: 17
olesen will become famous soon enough
Quote:
Originally Posted by nimasam View Post
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).
olesen is offline   Reply With Quote

Old   July 1, 2011, 13:52
Default
  #20
Senior Member
 
Nima Sam
Join Date: Sep 2009
Location: Tehran, Iran
Posts: 1,066
Blog Entries: 1
Rep Power: 14
nimasam is on a distinguished road
Send a message via Yahoo to nimasam
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.

Last edited by nimasam; July 3, 2011 at 04:53.
nimasam is offline   Reply With Quote

Reply

Thread Tools
Display Modes

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 On
Pingbacks are On
Refbacks are On



All times are GMT -4. The time now is 05:51.