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

Get cell volumes from lduSolver

Register Blogs Community New Posts Updated Threads Search

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   February 8, 2022, 12:59
Default Get cell volumes from lduSolver
  #1
Member
 
Join Date: Feb 2020
Posts: 90
Rep Power: 6
Shibi is on a distinguished road
Hello to all,


I would like to know if there is a way to retrieve the a reference to the scalarField storing the cell volume of the mesh from an ldusolver.

We could call the reference to the objectRegistry with:

Code:
const objectRegistry& a =  matrix().mesh().thisDb();
And possibly get the cell volumes with the cellVolumes() function from the primitiveMesh.

But I am getting the error:

Code:
error: invalid use of incomplete type ‘const class Foam::objectRegistry’
Would appreciate the help.
Shibi is offline   Reply With Quote

Old   February 9, 2022, 03:22
Default
  #2
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,689
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
The error means that objectRegistry was forward declared but not known completely in your code context.
Add an #include "objectRegistry.H" in your file.

Nonetheless not sure why you want to get at cell volumes in such a roundabout manner - they are directly available from the mesh - don't have to lookup from the registry.
olesen is offline   Reply With Quote

Old   February 9, 2022, 04:18
Default
  #3
Member
 
Join Date: Feb 2020
Posts: 90
Rep Power: 6
Shibi is on a distinguished road
Quote:
Originally Posted by olesen View Post
The error means that objectRegistry was forward declared but not known completely in your code context.
Add an #include "objectRegistry.H" in your file.

Nonetheless not sure why you want to get at cell volumes in such a roundabout manner - they are directly available from the mesh - don't have to lookup from the registry.
Thanks for the reply.

How so?

Inside the LDU solver, how can you get access to mesh volume?

Something like:

Code:
const fvMesh* myMesh = dynamic_cast<const fvMesh*>(&matrix().mesh());
 const scalarField& V = myMesh->V();
For the above code to work, you have to:

Code:
#include "fvMesh.H"
#include "volMesh.H"
and add to Make/options
Code:
EXE_INC = \
    -I$(LIB_SRC)/lduSolvers/lnInclude  \
    -I$(LIB_SRC)/finiteVolume/lnInclude 

EXE_LIBS = \
    -llduSolvers \
    -lfiniteVolume
Or something else?




As additional information this is being made in OF2106

Last edited by Shibi; February 9, 2022 at 05:23.
Shibi is offline   Reply With Quote

Old   February 9, 2022, 06:44
Default
  #4
Senior Member
 
Domenico Lahaye
Join Date: Dec 2013
Posts: 735
Blog Entries: 1
Rep Power: 17
dlahaye is on a distinguished road
Replace

const scalarField& V = myMesh->V();

by

const scalarField& V = myMesh.V();
dlahaye is offline   Reply With Quote

Old   February 9, 2022, 10:40
Default
  #5
Member
 
Join Date: Feb 2020
Posts: 90
Rep Power: 6
Shibi is on a distinguished road
Quote:
Originally Posted by dlahaye View Post
Replace

const scalarField& V = myMesh->V();

by

const scalarField& V = myMesh.V();
Not possible:

Code:
error: request for member ‘V’ in ‘myMesh’, which is of pointer type ‘const Foam::fvMesh*’ (maybe you meant to use ‘->’ ?)
   137 |     const scalarField& V = myMesh.V()
Shibi is offline   Reply With Quote

Old   February 9, 2022, 18:33
Default
  #6
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,689
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by Shibi View Post
Not possible:

Code:
error: request for member ‘V’ in ‘myMesh’, which is of pointer type ‘const Foam::fvMesh*’ (maybe you meant to use ‘->’ ?)
   137 |     const scalarField& V = myMesh.V()

I re-read your original question. You want to somehow get volume information from the lduMesh it seems? Not sure if I've properly understood what you are trying to do. In which file (please include the path) are you attempting to hack this in?
olesen is offline   Reply With Quote

Old   February 9, 2022, 18:43
Default
  #7
Member
 
Join Date: Feb 2020
Posts: 90
Rep Power: 6
Shibi is on a distinguished road
Quote:
Originally Posted by olesen View Post
I re-read your original question. You want to somehow get volume information from the lduMesh it seems? Not sure if I've properly understood what you are trying to do. In which file (please include the path) are you attempting to hack this in?
Yes. I want to get volume information from e.g., the PCG solver. the above code seems to work, although I do not know if there is a more straightforward way of doing this.
Shibi is offline   Reply With Quote

Old   February 14, 2022, 08:08
Default
  #8
Member
 
Join Date: Feb 2020
Posts: 90
Rep Power: 6
Shibi is on a distinguished road
Is the approach with dynamic_cast the best approach? Or is there something better?
Shibi is offline   Reply With Quote

Old   February 14, 2022, 08:16
Default
  #9
Member
 
Join Date: Feb 2020
Posts: 90
Rep Power: 6
Shibi is on a distinguished road
Quote:
Originally Posted by dlahaye View Post
Replace

const scalarField& V = myMesh->V();

by

const scalarField& V = myMesh.V();

To make this work I have to change:
Code:
const fvMesh* myMesh = dynamic_cast<const fvMesh*>(&matrix().mesh());

to

Code:
const fvMesh& myMesh = dynamic_cast<const fvMesh&>(matrix().mesh());
Shibi is offline   Reply With Quote

Old   February 16, 2022, 14:13
Default
  #10
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,689
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
I would normally write it like this:
Code:
const auto* meshPtr = isA<fvMesh>(matrix().mesh());

if (!meshPtr) FatalErrorInFunction .... 

const auto& myMesh = *meshPtr;
olesen is offline   Reply With Quote

Old   February 16, 2022, 16:09
Default
  #11
Member
 
Join Date: Feb 2020
Posts: 90
Rep Power: 6
Shibi is on a distinguished road
Quote:
Originally Posted by olesen View Post
I would normally write it like this:
Code:
const auto* meshPtr = isA<fvMesh>(matrix().mesh());

if (!meshPtr) FatalErrorInFunction .... 

const auto& myMesh = *meshPtr;
Hello Mr. Olesen.

Thanks for the input. It is shorter but on the background it should do the same thing: since the isA<fvMesh> function will do the casting.

Code:
template<class TargetType, class Type>
inline const TargetType* isA(const Type& t)
{
    const Type* p = &t;
    return dynamic_cast<const TargetType*>(p);
}


but I will adopt it and thank you for the conversion check.

Shibi is offline   Reply With Quote

Old   February 17, 2022, 13:48
Default
  #12
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,689
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by Shibi View Post
Hello Mr. Olesen.

Thanks for the input. It is shorter but on the background it should do the same thing: since the isA<fvMesh> function will do the casting.
...

Yes it is exactly the same under the hood, but saves other places in OpenFOAM where we previously had a check with isA<..> followed by a refCast<...> : not really any point performing the dynamic cast twice.

The other important reason for that particular design pattern is that if you have a dynamic_cast<Type*>(...) it will return a nullptr if the casting fails, but if you use dynamic_cast<Type&>(...) it will throw a bad cast exception if the casting fails. So much easier to use the pointer version and not deal with try/catch things.
olesen is offline   Reply With Quote

Old   March 10, 2022, 13:59
Default
  #13
Member
 
Join Date: Feb 2020
Posts: 90
Rep Power: 6
Shibi is on a distinguished road
One further question, if possible.

Can I create a variable as:
Code:
const fvMesh& meshRef_;
And initialize it in the constructor with a function as:
Code:
meshRef_(initMeshRef())
Code:
const Foam::fvMesh& Foam::myClass::initMeshRef() const
{
    const auto* meshPtr = isA<fvMesh>(matrix().mesh()); 
    if (!meshPtr)
    {
        FatalErrorInFunction
            << "Some Error message" << nl
            << exit(FatalError);
    }

    return *meshPtr;
}
Is this good practice? Or should I not define a reference as a class attribute ?
Sorry if this is too basic...
Shibi is offline   Reply With Quote

Old   March 10, 2022, 14:19
Default
  #14
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,689
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
No problem and not necessarily bad style to have a const or non-const reference as a member variable. However you most certainly cannot easily or reliably do what you have written. Should either use a static method or a file-scope local function that take the matrix as a parameter and return the reference.

Take a look at this code chunk and work your way upwards to see how it's done.
https://develop.openfoam.com/Develop...rDriver.C#L139


EDIT: if you need to, please check stackoverflow, google whatever. Try a small test class where you attempt to instantiate a member variable within the declaration of the constructor by calling a member function as part of that process (ie, what you've essentially scoped out here). See how successful you are. Try with clang as well to make sure that you are not relying on any special gcc "magic" to somehow save you. If you succeed or fail, please report back. Learning by doing is the only way to convince yourself here.

Last edited by olesen; March 11, 2022 at 08:48.
olesen is offline   Reply With Quote

Old   March 10, 2022, 15:27
Default
  #15
Member
 
Join Date: Feb 2020
Posts: 90
Rep Power: 6
Shibi is on a distinguished road
Quote:
Originally Posted by olesen View Post
Should either use a static method or a file-scope local function that take the matrix as a parameter and return the reference.
I did not quite understand this portion. This is to be placed inside a custom lduSolver (e.g., PBICGStab) so I should have the lduMesh reference to cast from the lduMatrix::solver.

Edit: I don't know how to use clang (is it possible to do wmake $someFlag clang?. Will it work if I compiled OF with gcc?), but the function appears to work fine. I guess that since the mesh object is unique and derived from the lduMesh that is being used to cast, there should not be a problem.

Last edited by Shibi; March 13, 2022 at 07:28.
Shibi 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
[snappyHexMesh] Creating multiple multiple cell zones with snappyHexMesh - a newbie in deep water! divergence OpenFOAM Meshing & Mesh Conversion 0 January 23, 2019 04:17
How to use "translation" in solidBodyMotionFunction in OpenFOAM rupesh_w OpenFOAM Running, Solving & CFD 5 August 16, 2016 04:27
[General] 2 datas on one plot Akuji ParaView 46 December 1, 2013 14:06
volScalarField for cell volumes and face surfaces AlmostSurelyRob OpenFOAM 2 December 13, 2010 05:24
SVN 1226 - Possible bug with cell centres and volumes philippose OpenFOAM Bugs 2 June 5, 2009 13:19


All times are GMT -4. The time now is 07:17.