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/)
-   -   GeometricField -> mesh() Function (https://www.cfd-online.com/Forums/openfoam-programming-development/223221-geometricfield-mesh-function.html)

Tobi December 31, 2019 07:25

GeometricField -> mesh() Function
 
Hi all,

I am just wondering, if I am getting things correct (but my analysis will show that I am not correct). Assuming that we do have an object based on a volScalarField which is actually a GeometricField. For this field, we can apply the function named mesh(). This function is not implemented in the GeometricField class but as this class includes the DimensionedField class, we can see that it is implemented there. As I cannot find any other function named »mesh()«, I expect that this is correct. The mesh function returns a reference to an object based on the class Mesh:
Code:

const Mesh&  mesh() const;
The class Mesh is actually
Code:

GeoMesh::Mesh Mesh;
So while we call the mesh function, e.g.,
Code:

volScalarField T = ...;


const Mesh& foobar = T.mesh();

we get an object of type Mesh (GeoMesh::Mesh). I guess there is already a mistake in my analysis as I have no idea how we can do the follow:


Code:

.... = T.mesh().ddtScheme("foobar");
The ddtScheme function here is based on the class fvSchemes, which is not inherited by GeoMesh. Actually the code:
Code:

T.mesh()
has to return somehow the reference to the fvMesh class because this class inherites the functions from the fvSchemes class. Furthermore, one can program the following:


Code:

const fvMesh& test = T.mesh();
However, I do not get the connection between the function mesh() that returns the fvMesh object. I am working with FOAM for 9 years now and I do not get the simplest things. Yesterday I saw a report on the TV that the youngest German hacker is 18 years old and has a security company in Hamburg with 23 employees. And I am not even able to connect the mesh() function call to the fvMesh class.


The only thing that I could image is the following:
  • the GeoMesh class is a template based on the class MESH
  • the GeoMesh is constructed somewhen using the fvMesh class
  • If so, the returned object of the DimensionedField mesh() function, which is of class Mesh (typedef GeoMesh::Mesh) would return an fvMesh object because the Mesh is:
Code:

typedef MESH Mesh
  • and while the returned object of the function mesh() of the DimensionedField class is of type Mesh, while MESH is the class template parameter of the GeoMesh class, the type Mesh could be a fvMesh (related to the construction of the GeoMesh object.


I hope that the last statement was clear :)


Any hint is welcomed.
Thanks in advance.

Zeppo January 2, 2020 16:11

Your analysis is quite correct. Here some code snippets to support your considerations:
Code:

//--- GeometricField.H ---
 template<class Type, template<class> class PatchField, class GeoMesh>
 class GeometricField
 :
    public DimensionedField<Type, GeoMesh>
 {


Code:

//--- DimensionedField.H ---
 template<class Type, class GeoMesh>
 class DimensionedField
 :
    public regIOobject,
    public Field<Type>
 {
 
 public:
 
    // Public Typedefs
 
        //- Type of mesh on which this DimensionedField is instantiated
        typedef typename GeoMesh::Mesh Mesh;
...
        //- Return mesh
        inline const Mesh& mesh() const;


Code:

//--- volFieldsFwd.H ---
 typedef GeometricField<scalar, fvPatchField, volMesh> volScalarField;


Code:

//--- volMesh.H ---
 class volMesh
 :
    public GeoMesh<fvMesh>
 {


Code:

//--- GeoMesh.H ---
 template<class MESH>
 class GeoMesh
 {
 
...

 public:
 
    // Public Typedefs
 
        typedef MESH Mesh;


Michael@UW January 3, 2020 17:03

volVectorField T
(
IOobject
(
"T",
runTime.timeName(),
mesh, // 1
IOobject::MUST_READ,
IOobject::NO_WRITE
),
mesh // 2
);

mesh 1 is a registered object only for IOobject and DimensionedField, I guess it is transformed to GeoMesh even it is fvMesh.

mesh 2 is the mesh where the filed lives, so it is volMesh for a volVectorField, which is actually fvMesh.

T.mesh is not accessible and you need only use the global variable 'mesh' itself, as all the volVectorFields use the same 'mesh', otherwise you may have U.mesh(), p.mesh() and so on (stagger mesh technique uses different meshes for different fields, but OpenFOAM use collocated mesh).

Above is just my analysis, please correct me if I am wrong.

Actually, I am always wondering why volVectorField constructed from IOobject uses the second mesh argument. Your analysis inspired me and partially solves the puzzle. The first mesh could be runTime which is also an registryObject. For simplicity, even if the IOobject is registered to a fvMesh, we still pass the second mesh to construct a volVectorField. What do you think about the construction mechanism?

Tobi January 3, 2020 19:10

The object mesh in your post is based on the fvMesh class. Both, your first end second mesh are identical, it is the same object but you know that. The only nice magic that happens here is the fact that the programming language is smart enough to return the object needed at the corresponding line but only due to the fact that the constructors are having the fvMesh class as argument or the code is smart enough to return the correct object.

The second mesh is of type Mesh which is actually GeoMesh::Mesh Mesh and the template type MESH is set to fvMesh. So here things are clear. The first mesh will return the registry object.

Actually I don't know your Intension for your post as it is not related to mine and Zeppo already showed that my analysis was correct. Using this information you can resolve your topic.
By the way. T.mesh is not even a function. So what should this peace of code do? I guess if you want direct access you have do do it with the scope operator.

granzer March 22, 2020 03:56

Quote:

Originally Posted by Tobi (Post 753769)
The object mesh in your post is based on the fvMesh class. Both, your first end second mesh are identical, it is the same object but you know that. The only nice magic that happens here is the fact that the programming language is smart enough to return the object needed at the corresponding line but only due to the fact that the constructors are having the fvMesh class as argument or the code is smart enough to return the correct object.

The second mesh is of type Mesh which is actually GeoMesh::Mesh Mesh and the template type MESH is set to fvMesh. So here things are clear. The first mesh will return the registry object.

Actually I don't know your Intension for your post as it is not related to mine and Zeppo already showed that my analysis was correct. Using this information you can resolve your topic.
By the way. T.mesh is not even a function. So what should this peace of code do? I guess if you want direct access you have do do it with the scope operator.

Can you please tell me how the first 'mesh' object is an object of type objectRegistry? I have seen that in place of the first 'mesh' we can also have 'runTime' object, which is an object of class Time. So if runTime is a object of class Time how can it be an object of class objectRegistry too?

Zeppo April 1, 2020 12:01

Quote:

Originally Posted by granzer (Post 762418)
Can you please tell me how the first 'mesh' object is an object of type objectRegistry? I have seen that in place of the first 'mesh' we can also have 'runTime' object, which is an object of class Time. So if runTime is a object of class Time how can it be an object of class objectRegistry too?

Both Time and fvMesh classes are derived from objectRegistry class.

olesen April 2, 2020 10:16

Quote:

Originally Posted by Zeppo (Post 763848)
Both Time and fvMesh classes are derived from objectRegistry class.


It does get a bit confusing sometimes, but you can think of an objectRegistry as being a database for holding objects (objects of type regIOobject to be specific). Since the objectRegistry itself is derived from a regIOobject, an objectRegistry can thus contain other object registries, and can potentially have a parent registry as well. Time is a special case of an objectRegistry that is also used to define the time coordination for multiple registries.


At this stage it probably helps to think in terms of a file-system. The objectRegistry is analogous to a directory, the regIOobject is analogous to a file/directory.

granzer April 7, 2020 08:04

Quote:

Originally Posted by olesen (Post 763942)
It does get a bit confusing sometimes, but you can think of an objectRegistry as being a database for holding objects (objects of type regIOobject to be specific). Since the objectRegistry itself is derived from a regIOobject, an objectRegistry can thus contain other object registries, and can potentially have a parent registry as well. Time is a special case of an objectRegistry that is also used to define the time coordination for multiple registries.


At this stage it probably helps to think in terms of a file-system. The objectRegistry is analogous to a directory, the regIOobject is analogous to a file/directory.

Yes exactly! I have come to visualize it as the Linux file system with runTime taking the place of 'root' directory and all other objectRegistry type objects coming under runTime object.
Am I right in understanding that a class like 'volScalarField' is also derived from 'regIOobject' and an object of volScalarField, say T, can be called a volScalarObject or a regIOobject?

olesen April 7, 2020 14:09

Yup, your "T" is a volScalarField, which derives from a regIOobject. Continuing with the filesystem analogy, the volScalarField is like a file (not a directory). Your choice if you want to deal with it along with other "files" (eg a volVectorField) or want to dispatch something particular to its type. In the latter case, you can dynamic cast it from the regIOobject to the volScalarField.

Elol November 11, 2020 11:31

Hi Foamers,

I just have a simple question, I don't know if it is related to this thread or not. Anyway, If I want to calculate something like that

K= delta x^2 / deltat

which x is the local cell distance (x,y,z) and deltat is the runTime.deltaT(). what function or how exactly represent delta x^2 in terms of programming ?

Thanks in advance.

Tobermory November 19, 2020 11:33

Umm ... this topic seems to be completely unrelated to the previous one, so I hesitate to respond at all. Please start a new thread when you have a new, unrelated question ... you are also more likely to get a reply!

As for your question, take a look at a utility like postChannel. You can get the cell centre coords from

Code:

const vectorField& centres = mesh.C();
and that will be a start. Good luck.


All times are GMT -4. The time now is 01:21.