lookupObject for <volScalarField>("p") interFoam
Hi everyone,
I'm trying to implement Coulomb type viscosity model and I use interFoam solver. In calcNu() in my Coulomb.c, I have const volScalarField& pp=U_.db().objectRegistry::lookupObject<volScalarF ield>("p"); volScalarField nu__=mu0_/(max(sr(),dimensionedScalar("VSMALL", dimless/dimTime,VSMALL)))*pp/rho_; When I compiled the library, there is no error. However, when I included the library to run with interFoam I got an error: --> FOAM FATAL ERROR: request for volScalarField p from objectRegistry region0 failed available objects of type volScalarField are 4 ( alpha.water (1.41421*mag(symm(grad(U)))) p_rgh alpha.air ) I understand that interFoam solves for p_rgh (p-rho gh) instead of p, so there is no need for p to present in /0. However, p is written in the later time directories which means p has been calculated. Any advice how to obtain field p? Thank a lot! Nuttita |
I don't have time to trace the entire src code for you, but this is my hypothesis (check for yourself if it's true):
In createFields.H of interFoam the following is found: Code:
Info<< "Reading field p_rgh\n" << endl; p_rgh is constructed based on a mesh. p is constructed based on a tmp<volScalarField>. Now, I do not know where exactly it happens, but I do know that Fields (e.g. volScalarField) should register themselves in the objectRegistry. This happens by the regIOobject class, which is a (distant) parent of volScalarField. The "mesh" is the objectRegistry. That is, no objectRegistry is passed in the constructor of the p-field, hence it cannot register itself. Therefore, you cannot obtain p. Two different workarounds:
|
Hi all,
@nuttita calcNu method is called during: 1. construction of incompressibleTwoPhaseMixture. 2. mixture.correct() call. In the first case pressure field is not available yet, as it is created after mixture object in createFields.H. But it is available on the first mixture.correct() call (just before construction of velocity equation). So to avoid error, you can check if pressure field is available using foundObject method (http://cpp.openfoam.org/v4/a01730.ht...85a5590fbebd84). If pressure is not there yet, return 0; otherwise use it. |
Hi Kevin and Alexey, thank you for your quick replies.
Kevin, you're right I should construct p the same way as p_rgh in createFields.H. However, the location to construct p is also important. As Alexey mentioned calcNu method is call during construction of incompressibleTwoPhaseMixture. So I need to construct p before that call. Here is my solution. OLD createFields.H code: Quote:
code: Quote:
Any discussion or better solution are welcome! Thanks! Nuttita |
Hi,
@nuttita Unfortunately you have missed my point. You keep original createFields.H BUT in your model change Code:
const volScalarField& pp=U_.db().objectRegistry::lookupObject<volScalarField>("p"); Code:
const objectRegistry& db = U_.db(); |
Now I see your point. Thanks for your help, alexeym.
|
Dear everyone,
By taking a look at objectRegistry::lookupObject(const word& name) method implemented in ObjectRegistryTemplates.C you can see this method iterates through registered objects and returns the object with specified name and Type. If there is no match with the specified name and Type with those registered a Fatal Error happens and you will have your run stopped. So it’s essentially important to make sure that your object is registered in db before calling the lookupObject. For example if you call lookupObject() method before creation and registration of the object you will have Error. And on the other hand by calling the lookupObject() method after registration of the object you won’t have any problem. Code:
const volScalarField& pp = U.db().lookupObject<volScalarField>("p"); //Incorrect Code:
volScalarField p Cheers, |
Dear hasansh1986,
And what if we are not in control of field creation? For example, we are writing, library, which could be used with arbitrary solver? |
If existence of the object is crucial in the algorithm you're implementing you need to make sure that the object is already created (for instance you can create the object in constructor of you class). In these cases FATAL ERROR helps you to realise that something is going wrong in your implementation. On the other hand, if the object is optional in order to prevent FATAL ERROR it's a good practice to check if the object is registered or not (if(db.foundObject<volScalarField>(someName))).
|
Quote:
Kevin, I like your second suggestion of constructing p when I need it. You also mention that I have to adapt my code so I can access mesh, runTime, etc... I am writing a new functionObject where I started off with foamNewFunctionObject, i.e. minimal amount of libraries are included. How do I make mesh, runTime, etc. accessible within my code? And also, should I define my volScalarField in my .C or .H file? Thankful for help here! David |
Quote:
no idea what you are trying to do :). Looking into this https://cpp.openfoam.org/v7/function...8H_source.html lines 131-134 access to Time and polyMesh is guaranteed. You may try this: Code:
const polyMesh& mesh_ = this->mesh_; |
All times are GMT -4. The time now is 12:51. |