|
[Sponsors] |
September 21, 2016, 23:23 |
OOP CFD Sample Code in C++
|
#1 |
New Member
M
Join Date: Sep 2016
Posts: 1
Rep Power: 0 |
Hi,
I am learning CFD and want to make the change from MATLAB to C++ for my programing language. The reason is that I also want to pursue some other programming projects and C++ is a common language software is done in. Anyways, I want to do my CFD codes using Object Oriented Programming OPP. Again, this would help me with my later goals. I have basic knowledge in C++ and a general idea of how OPP works, but it seems like there is a very standard procedure people use for OPP in CFD. Ex. Making a vector on object, making boundary conditions objects, etc. I can't find too much literature out there specifically on how to use OOP in CFD, but I have a few bits and pieces of things I have gathered from different websites. It would REALLY help me learn though if I had a sample code so I can get an idea of how it is set up. Can somebody please provide a sample CFD code that is in C++ and uses OPP? It doesn't have to be super complex or anything from a CFD perspective, I just want to see the general structure of the code and how the OOP is incorporated. I would really appreciate it. Thanks in advance! |
|
September 22, 2016, 00:15 |
|
#2 |
Senior Member
Michael Prinkey
Join Date: Mar 2009
Location: Pittsburgh PA
Posts: 363
Rep Power: 25 |
OpenFOAM is C++...of a sort, anyway. It uses lots of templates to generate a CFD domain specific language. It is probably the logical end point of OO CFD. Whether that is an unalloyed good or not is an open question. Some of what is below is more opinion than established fact, but it is borne out of long experience.
I personally prefer "C-style" C++. I use objects and other C++ concepts where they are useful and more basic C code where performance is critical. There are many performance pitfalls that you can run into if you make your code too object oriented. An obvious approach to OO CFD might be to make a "cell" object and then layer all of your unknowns into the cell, create cell functions, and formulate the mesh as a list of cell objects. Your solver would then iterate over the cell list and call functions that pass and return cell and face objects to solve the problem. Again, this is a very appealing OO way to approach the problem. But, if you code up a solver like that (and I have), you will not see the same performance you can get from a more traditional C or Fortran code. The higher-level the description of the problem, the fewer optimizations are made available to the compiler. That seems to be an immutable law. You see many discussions regards Arrays-of-Structs (AoS) vs Stucts-of-Arrays (SoA) with regard to memory layout and how that impacts solver performance. And it is not necessarily clear which is better when you start to build your code. But when you start by defining objects and building up the "nice" mechanisms to interact with those objects, you are implicitly dictating the memory layout by your object definitions--and once you have those complicated constructs assembled, you will find it very difficult to pivot to alternative structures later. Again, OpenFOAM is a great example of this--marvelously designed object-oriented CFD but extremely difficult to modify at its core...there are just so many interlocking pieces. C-style structs, arrays, and linked lists are not nearly as elegant and are more cumbersome to code then some abstracted C++ object form, but because all of the details of the looping mechanisms and the data accesses are not hidden in objects, it offers more flexibility and a more shallow learning curve, at least in my experience. As I say, I generally like to write C++ but use the ++ parts with great care. I do define Vector, Tensor, and SymmetricTensor as objects and define some operator overloading to make cleaner syntax, but these need to be done with care to avoid hamstringing the compiler. A little googling will turn up discussions about these issues (https://en.wikipedia.org/wiki/Expression_templates) One valuable instance where OO is very useful is in defining mesh information, especially when computing volumes, area, centroids--tasks that are usually just part of the initialization and therefore, not as performance/optimization critical. I define a tetrahedron object with area, centroid, etc member functions: Code:
class tetrahedron { private: vector A,B,C,D; public: tetrahedron(vector v0, vector v1, vector v2, vector v3) { A = v0;B = v1;C = v2;D = v3; } inline vector centroid(void) { return 0.25*(A + B + C + D); } inline scalar volume(void) { const scalar oneSixth = 1.0/6.0; return oneSixth*fabs((A - D)&((B - D)^(C - D))); } } Code:
class pyramid // // Pyramid is constructed from two tetrahedra. // // This assumes that (b0,b1,b2,b3) all lie in the same plane! // // Constructor order is very important for base vertices, otherwise, we could // have a "bowtie" base. Vertices must be enumerated as a loop. // // b0-------b1 // | . | // | . | // | . | // | . | // b3-------b2 // { private: tetrahedron t0, t1; public: pyramid(vector b0, vector b1, vector b2, vector b3, vector t) { tetrahedron t0, t1; t0 = tetrahedron(t,b0,b1,b2); t1 = tetrahedron(t,b0,b2,b3); } inline scalar volume(void) { return t0.volume() + t1.volume(); } inline vector centroid(void) { scalar Vt0,Vt1; Vt0 = t0.volume(); Vt1 = t1.volume(); return (Vt0*t0.centroid() + Vt1*t1.centroid())/(Vt0 + Vt1); } } So, I know this is probably not answering your question, but I hope that it at least encourages you to not just run headlong into implementing some over-engineered OO formulation assuming that elegance will translate into performance. There are many references that discuss do's and don'ts of OO high-perofmrnance programming and most of them tend to echo the things I have learned through trial and error. Good luck. |
|
May 21, 2020, 02:03 |
|
#3 |
New Member
Join Date: Aug 2018
Posts: 2
Rep Power: 0 |
Did you find any source that helped you with the same?
|
|
May 21, 2020, 05:18 |
|
#4 |
Senior Member
|
The answer provided by Michael back then is still relevant, and in practice it somehow meant that you better not overkill OOP in CFD, where performance and simplicity are preferred over computer science purism and formalism.
If you want to learn oop, developing a GUI is a much better suited exercise than doing it in CFD. But let me give you also another perspective for coding in CFD. You should ask yourself: what is that you want to achieve in writing your CFD code? It turns out that, if you do that for large, professional codes, some of the following apply: 1) You want as little code as possible (because it easier to maintain, especially when a full picture of the code is needed) 2) You want the code to be as fast as possible (obvious) 3) You want the coding to be as trivial as possible (easier to maintain as well and anyone can jump in without specific knowledge) Somehow implicit in the points above is the fact that you want your code to be easily extendable to additional features and models. I consider it implicit because that's one of the points of having little, trivial pieces of code. In this picture OOP is just a tool as any other feature of your programming language of choice. A typical scenario is when you have to do something and you start thinking: wow, if I could do this, I could do the job in 5 minutes and this would also help here and there. But OOP is just one of the tools that a programming language offers. So, the suggestion is to use the language at your advantage, not the other way around (i.e., I have to use OOP). If it turns out that OOP is the way to go, then let it be. But, it is not uncommon at all the case where, in order to have OOP, you end up writing a lot of boilerplate code that adds nothing to the task and will only add pain if something needs to be changed later. So, the take home message is to avoid "learning OOP in CFD" and looking for good examples of it, because that is a not well posed question. Learn CFD, coding and OOP as separate things and use them properly for the task at hand. Last edited by sbaffini; May 21, 2020 at 06:37. |
|
May 21, 2020, 08:45 |
|
#5 |
Senior Member
Arjun
Join Date: Mar 2009
Location: Nurenberg, Germany
Posts: 1,291
Rep Power: 35 |
OOP is not the end of world and should not be applied just for the sake of it. It could be very useful tool if used properly and could be a big mess if applied without proper thought to it.
|
|
Tags |
c++, cfd, object oriented, oop, sample code |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Debugging technics - CFD code developing | leo_NM | Main CFD Forum | 2 | June 9, 2016 12:22 |
CFD code structure (F90) | ma | Main CFD Forum | 4 | January 10, 2005 21:47 |
CFD for fans & blower housings | David Carroll | Main CFD Forum | 8 | August 24, 2000 18:25 |
Since Last June | John C. Chien | Main CFD Forum | 3 | July 12, 1999 10:38 |