|
[Sponsors] |
Trying to understand OpenFOAM source code (pTraits.h) |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
April 21, 2019, 23:45 |
Trying to understand OpenFOAM source code (pTraits.h)
|
#1 |
Senior Member
Lee Strobel
Join Date: Jun 2016
Posts: 133
Rep Power: 10 |
I'm trying to read and understand some of the OpenFOAM source code (specifcally, version 6 from openfoam.org). I've chosen to start at pTraits.h, as it seems quite foundational. I was trying to understand some of the classes relating to vector fields and point fields, but they seem to be using this header as a base.
Anyway, I have some basic knowledge of C/C++; however, I am confused by some of the syntax that is being used: Firstly, at line 44: Code:
class Istream; The Istream class clearly isn't being defined here; however, there are no other header file being included. Where does this Istream come from and what does it do? I can see that it is being used in one of the constructors further down. Secondly, lines 52-53: Code:
: public PrimitiveType I don't understand what the colon means in the class template declaration, or what the 'public PrimitiveType' is for. Also, to summarize what this header is doing: it is providing a basic template class, with a couple of constructors for primitive objects - is that correct? In general, I'm not sure if this particular file is a good place to start delving into the OF codebase - any advice on that would be much appreciated. |
|
April 22, 2019, 09:09 |
|
#2 |
Senior Member
Tom-Robin Teschner
Join Date: Dec 2011
Location: Cranfield, UK
Posts: 211
Rep Power: 16 |
these are just some c++ specific ways of doing things.
The "class Istream" is a forward declaration of the class Istream and is just here so that your linker doesn't complain. You could remove this and include a header file to the actual implementation of the class, i.e. put #include "IStream.H" at the top, but that includes the whole header. I guess it comes down to your personal preference and coding style, but generally speaking, for large projects such as openfoam you should try to avoid including header files and use forward declaration whenever possible. The forward declared class just tells the linker not to complain and to assume that such a class exist. Of course, this class needs then to be declared somewhere else which the compiler / linker can find. Regarding your second question, the construct Code:
template<class A> class B : public A The above construct allows you to use methods from class A in class B but you don't need to know what A is, you just need to make sure that it will have the required method that you want to call. The advantage here is, that class A can have many different versions while class B doesn't care what A is, it just makes use of its interface (data abstraction, another important concept in C++). Now this all sounds very complicated and dry without an example, so lets say we want to write a CFD solver and we want to have different reconstruction / interpolation scheme, say a first and a second order accurate one. One way of implementing that with the structure given in the pTraits class could look like this: Code:
#include <iostream> class firstOrderReconstruction { public: void reconstruct() { std::cout << "Implement a first order reconstruction here" << std::endl; } }; class secondOrderReconstruction { public: void reconstruct() { std::cout << "Implement a second order reconstruction here" << std::endl; } }; template<class scheme> class reconstructor : public scheme { using scheme::reconstruct; public: void applyReconstruction() { reconstruct(); } }; int main() { reconstructor<firstOrderReconstruction > firstOrder; reconstructor<secondOrderReconstruction> secondOrder; firstOrder.applyReconstruction(); // will print "Implement a first order reconstruction here" secondOrder.applyReconstruction(); // will print "Implement a second order reconstruction here" return 0; } As a side note, you could have achieved the same behaviour above with dynamic runtime polymorphism, i.e. using virtual functions, that would have looked like this Code:
#include <iostream> class reconstructor { public: // we could also drop the = 0 at the end, but in this way we force // all classes that derive from this to implement this virtual function // (now called a pure virtual function) virtual void applyReconstruction() = 0; }; class firstOrderReconstruction : public reconstructor { public: void applyReconstruction() final override { std::cout << "Implement a first order reconstruction here" << std::endl; } }; class secondOrderReconstruction : public reconstructor { public: void applyReconstruction() final override { std::cout << "Implement a second order reconstruction here" << std::endl; } }; int main() { firstOrderReconstruction firstOrder; secondOrderReconstruction secondOrder; firstOrder.applyReconstruction(); // will print "Implement a first order reconstruction here" secondOrder.applyReconstruction(); // will print "Implement a second order reconstruction here" return 0; } Fairly exhaustive, but I feel that c++ question are rarely answered in just two sentences. Hope that that gives you a better idea. |
|
April 22, 2019, 22:42 |
|
#3 |
Senior Member
Lee Strobel
Join Date: Jun 2016
Posts: 133
Rep Power: 10 |
Hi t.teschner, thank you very much for the great explanation, with the examples. This is very helpful, thank you.
I think I have a basic understanding of Polymorphism and Inheritance, but I am reading some more into them and how they are implemented in C++. I'm getting the impression that OF makes quite extensive use of these concepts, so I will need to understand them more deeply. Your explanation and examples of the polymorphism are very helpful. So, the pTraits class can inherit from a range of different classes and 'PrimitiveType' is the template 'placeholder' for the type of class it inherits from? One thing I am still a bit confused about though is what the pTraits class is doing. It seems to be inheriting these two constructors from whichever class PrimitiveType is referring to (the first one looks like a copy constructor - is that correct?). However, as far as I can see, it doesn't seem to be modifying them in any way. So, what is the function of the pTraits class? |
|
April 23, 2019, 02:22 |
|
#4 |
Senior Member
Tom-Robin Teschner
Join Date: Dec 2011
Location: Cranfield, UK
Posts: 211
Rep Power: 16 |
Yes, openfoam and makes great use of C++'s object orientated features (which allows us to type our equations in a pain-free manner ...). And yes, you can see the template parameter as a placeholder, that is exactly what they are.
I don't have the code currently in front of me but I would guess that this class just provides an interface for other classes which derive from this class (so that any derived class has a constructor that accepts the template argument's parameter or an Istream object). So its use would have to be evaluate in the context of a derived class. The term copy constructor is not correct in this context, for that the constructor would accept an argument of the class itself, i.e. the copy constructor would look something like pTraits(pTraits& p). Hope this helps. Last edited by t.teschner; April 25, 2019 at 15:59. |
|
Tags |
c++, code, openfoam 6 |
Thread Tools | Search this Thread |
Display Modes | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Custom Thermophysical Properties | wsmith02 | OpenFOAM | 4 | June 1, 2023 15:30 |
polynomial BC | srv537 | OpenFOAM Pre-Processing | 4 | December 3, 2016 10:07 |
OpenFOAM without MPI | kokizzu | OpenFOAM Installation | 4 | May 26, 2014 10:17 |
OpenFOAM on MinGW crosscompiler hosted on Linux | allenzhao | OpenFOAM Installation | 127 | January 30, 2009 20:08 |
DecomposePar links against liblamso0 with OpenMPI | jens_klostermann | OpenFOAM Bugs | 11 | June 28, 2007 18:51 |