CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   Main CFD Forum (https://www.cfd-online.com/Forums/main/)
-   -   How to write a good cfd code in fortran ? (https://www.cfd-online.com/Forums/main/174921-how-write-good-cfd-code-fortran.html)

Dhairya July 20, 2016 23:27

How to write a good cfd code in fortran ?
 
Hello everyone, I am a student who is trying to learn cfd on his own and went through some good books like patankar's and versteeg's, and these books give a good basic idea and I could even write some basic codes in fortran (like lid driven cavity, natural convection in square cavity..). However, these books do not give a clear picture of how a code should be written ( I am little weak in programming but am working hard). The codes I write and the fortran codes others have posted online and very different (mine are very very naive :confused:).
So could you please suggest some good sources that help me understand how to write fortran codes through the point of view of a cfd programmer and how to do the post processing like drawing isotherms or streamlines.
I would really be very grateful for your help. :)

kaya July 21, 2016 07:15

I don't have an answer to your question but here's my contribution.

First of all I would not use fortran as a tool to learn cfd. seriously. Having said that, if I were to write a parallel fortran code I'd code everything in matlab and translate it from there to fortran. I would only do this if I need performance and cluster-parallelization, else I wouldn't bother.

Before I translate, I'd make sure that I have the parallelization architecture ready in my mind that I know what goes where and write the code in this way, this would allow me not to make drastic changes in the middle of the way.

I am not sure if there is a best-practices-fortran-cfd-coding book but there are easy to find books that explain how to increase performance in fortran coding that talk about loops, subroutines, dynamic arrays etc.

I'd keep main.f file super simple that it would make routine calls that are intuitively named. Also I'd add comments all over the code, not for anyone else but for my self. Because at some stage you'll realize that you forgot how that module you made a year ago was working.

I like keeping memory usage in control that I'd allocate some bunch of physical memory spaces and link pointers to that, this allows to be more conservative on memory but complicates the thing that you won't be able to access all the arrays at all the stages of the time step. This is a matter of taste, not really a need because today's computers are quite fat in RAM memory.

I'd keep it as simple as it can get. Some sources will tell you to do nasty stuff to incrase performance i.e. you may gain a bit by writing
Code:

do i=1,Nx
  do j=1,Ny
    do k=1,Nz
      a(k,j,i)=b(k,j,i)+c(k,j,i)
enddo;enddo;enddo

but I'd keep it like
Code:

a=b+c
and rely on compiler's optimization because compilers are clever enough.


For the parallelization OpenMP is easy to implement that you parallelize loops but use MPI if you're aiming clusters. Mixing these two is a bit stinky.


last but not least, debug on the fly. check arrays with the matlab version while coding, don't wait to close the time loop while coding. This would actually save some time.


I wouldn't use fortran to post process, I'd work with matlab and if I need something fancy I'd use paraview or similar softwares.

pitto August 5, 2016 06:20

Personally, I would not recommend going into coding at first when you are starting off with CFD.

One good practice could be using OpenFOAM or SU2 (open source solvers) and run classic test cases and post process using Paraview.

As you read about the various mathematics of CFD solvers you could go and check how these are implemented in these codes. And then compare your own understanding.

On another note, you can probably download various parts of the codes online. Like codes for solving system of equations using Runge-Kutta schemes etc.

Using FORTRAN should not be the motive but understanding and learning about the algorithm must be the primary goal.

Coming to scripts I would recommend learning Python and Parallel programming for a future prospect of going deep into this field. You can find multiple courses on these on coursera.com.

I hope this was helpful at some level.

Good luck!

m.javad August 7, 2016 04:34

paralleling
 
hello everyone. does anyone know how to parallel CPU cores in fortran codes ? my numerical method is lattice boltzmann

kaya August 7, 2016 06:55

check out quantum computing :D

t.teschner August 7, 2016 13:50

fortran is a perfectly fine programmign language, especially in cfd. although i am quite fluent with c++ with mpi, openmp, cuda, openGl etc., i still use fortran if i want to put something simple together, to check. and even some medium sized codes are perfectly fine to do with fortran.

now, regarding the original question. to start coding cfd, i would start with simplified forms of the navier-stokes equations. advection equation, advection-diffusion equation, then full navier-stokes equation. it took me a while to wrap my head around the artificial compressibility method (mainly because there is not much on that in comparison to the SIMPLE scheme for example and the quality of the description were all a bit questionable), but it seems all description of SIMPLE reduce to staggered grids (another complication) and a presentation where it is easy to get lost in all the nomenclature (ap, an, ae, aw, as, F, D, b ...) in the end you can't recognise the original equation anymore and thats where i find it gets tricky to debug, especially if it is your first time doing so. the reason i advertise the artificial compressibility method is because it is dead simple, pressure comes from the continuity equation and that is plugged in into your momentum equation, you can have a navier stokes solver within 200 - 300 lines of code. This guy (https://github.com/xuaoxiqi/Computat...0Cavity%20Flow) has working examples for Artificial Compressibilty and SIMPLE for the lid driven cavity, it might be a useful resource.

In terms of coding, there are many things that you can take into account, i would just be consistent with what you do. at first i would not spend any time on optimising your code, the compilers have pretty good compiling optimiser. the easiest is, assuming you use gfortran and you want to compile, say navierstokes.f90 to compile with

gfortran -O2 navierstokes.f90

the -O flag tells the compiler to optimise. Some will jump at my neck now and say to use -O3 for even better performance, but some compiler optimisation are actually so agressive that they could cause some unintentional outcomes. it just saves you later some very frustrating debugging (which shoud be done without any -O flag anyways).

Once you have mastered that, 2D, 3D navier-stokes it is really up to what you want to do next. parallising is certainly something i would look into, but not at the stage you are now, where you have to learn the basics. openMP, as said before, may not be the best language for cluster computing (infact, it is pointless), but if you just want to learn how to write a prallel code and/or you just want to run on your desktop/laptop machine, openMP is very effective and straighforward. just as an indicator, i once parallelised a code using openmp and it took about 10-20 min where i achieved an efficiency of about 80%, it was good enough for me for that particular application. if i were to do the same with MPI, that would have been easily a couple of days (mpi needs a specific code structure, openmp is more flexible).

in terms of post processing, the simplest way is just to write an output that tecplot or paraview can read. in the repository above, the guy is using a fairly simple output format for tecplot which you can use for your own solver. also, this website might be useful if you want to look at example files and to learn from them (http://people.sc.fsu.edu/~jburkardt/data/tec/tec.html)

sbaffini August 9, 2016 07:33

I would add that:

1) Fortran 2008 can easily manage most of the modern programming needs if you know how to use it

2) If you just want to make a lid driven cavity solver and learn Fortran in the meanwhile, then just do it without too much thinking; a basic fortran textbook is just what you need. I read almost all the available books on Fortran and i can suggest (for several reasons and with no specific order):

- Markus: Modern Fortran in Practice, Cambridge
- Clerman, Spector: Modern Fortran - Style and Usage, Cambridge
- Chapman: Fortran 95/2003 for Scientists and Engineers, Mc Graw Hill
- Metcalf, Reid, Cohen: Modern Fortran explained, Oxford

I'm not saying to limit to just theese books, as there are several others, some of which have useful additions, even if somehow dated or not so good as these ones. But i found these the most useful.

3) You might want to go parallel for the same reason of the previous point, learning. In this case i suggest MPI, which is much more expendable and because you need to be very good at OpenMP to achieve the same or better performance of MPI on a shared memory machine. In this case you just need two books:

- Gropp, Lusk, Skjellum: Using MPI, MIT Press
- Gropp, Hoefler, Thakur, Lusk: Using Advanced MPI, MIT Press

However, Fortran 2008 also has co-arrays, and you can go parallel just with Fortran. Obviously, you need to check the current status of the implementation:

https://gcc.gnu.org/wiki/Fortran2008Status

And a book on this is coming out right now:

- Numrich, Reid: CoArrays: Parallel Programming in Fortran, C&H/CRC

4) If you want to do some serious CFD coding, like assembling a full capability code, the matter is slightly different, but not because of the Fortran. The previous suggestions are still valid but, now, you need to design your product (code) as in all the engineering stuff. This is where most Fortran developers fail, as they are typically not exposed to this.

A route i usually find useful is to first have clear what i want to achieve, how i want the user experience to be with the code. For example, if you use Fluent, you might start wondering how some stuff is done, like reading two grids in sequence and uniting them to form a single one, a text user interface to interact with code (vs the OpenFoam approach of solvers which just do n iterations and exit), etc.

Once you have collected all the specs, you start developing. For large codes however, you need to do this in layers, from bottom to top. For example, you know you are going to solve sparse linear equation systems in parallel, so you better first develop the undrlying data structure before even thinking of CFD. In parallel, there are a certain bunch of operations you are going to need frequently, so you better have them first (and cleverly written), so you can use them with all the data structures you develop in the following.

In general, the most part of the code you can write which is independent from the rest, the better it is. For example, a cell centered finite volume scalar convection scheme for an unstructured grid is something which needs cell variables and gradients in two adjacent cells, the massflux on their common face and few other geometric factors. The code for such scheme should be placed in an independent module, and not embedded in the main code. The same is true for the linear algebra, computational geometry, wall functions, etc. The most part you can develop and test independently from the others the better it is.

Note how this has nothing to do with Fortran. I've seen a lot of C/C++ codes which do not respect even such basic software engineering practices.

5) Your only problem with Fortran will be that, at the end, after you have developed all such skills (in a language which, in my opinion, is much less verbose than C or C++, so that you can focus on the code and not coding), then you end up with almost no possibility to use such skills in a real job. For example, i know of just a couple of commercial codes developed in Fortran (if i am not wrong, Fastran, AVL Fire... maybe Ricardo). So, you might want to consider C/C++ because of this.

6) If you want to look at some open source codes developed in Fortran, look at:

- https://github.com/ElmerCSC/elmerfem
- http://www.pflotran.org/
- https://ccse.lbl.gov/BoxLib/index.html
- https://nek5000.mcs.anl.gov/
- https://github.com/szaghi/OFF
- http://people.uniroma2.it/salvatore....emo/index.html

Code_Saturne (http://code-saturne.org/cms/download/Source-code-access) also has several Fortran parts.

I do not advocate any of the programming practices used by these codes (actually, most of them do quite the opposite of what i just said) but, still, these certainly are important examples of fortran codes.

Dhairya August 19, 2016 09:08

Thank you all for valuable replies. All the replies were extremely helpful and I am really grateful to you all for showing me the path through which I could improve upon my cfd coding skills.

arjun August 20, 2016 14:55

Quote:

Originally Posted by Dhairya (Post 614674)
Thank you all for valuable replies. All the replies were extremely helpful and I am really grateful to you all for showing me the path through which I could improve upon my cfd coding skills.


To be truthful you will be much better off learning c++ than fortran for cfd. If I am not forced I would never write anything in fortran.

I have been developing cfd code and I am so glad that I am doing it in c++. Thanks to framework, it does not take time to add new models and new things in code.
It took me 1 week to add mixture multiphase and 1 day to add fractional solver.

If the code was in fortran, I can not imagine how it was possible in a multi-region multiphase solver capable of multiprocessor calculations.

Mhy personal advise, dont invest in fortran because eventually you would want to do something advance.

FMDenaro August 20, 2016 18:11

I read this post several times during these days, not sure if writing or not my idea about it...however, the main concern I have is about tthe term "good code". That sounds nothing for me... you can have an astonishing code written in a perfect and modern fortran, working efficiently in parallel and so on. It is good? and for doing what? It is still good if it has a simple incompressible fluid model for only cartesian geometry and uses first order in time and space?
So, I wonder what you think about....

arjun August 21, 2016 09:04

Quote:

Originally Posted by FMDenaro (Post 614795)
I read this post several times during these days, not sure if writing or not my idea about it...however, the main concern I have is about tthe term "good code". That sounds nothing for me... you can have an astonishing code written in a perfect and modern fortran, working efficiently in parallel and so on. It is good? and for doing what? It is still good if it has a simple incompressible fluid model for only cartesian geometry and uses first order in time and space?
So, I wonder what you think about....

This is why I also did not write. CFX is an example of code that is fortran and does everything other codes do.

I personally find it much easier to do with C++ because coding is done mostly for change, reuse and augmentation of code. Many times person just writes code for 1 purpose for them language makes no difference.

sbaffini August 22, 2016 11:19

Quote:

Originally Posted by FMDenaro (Post 614795)
I read this post several times during these days, not sure if writing or not my idea about it...however, the main concern I have is about tthe term "good code". That sounds nothing for me... you can have an astonishing code written in a perfect and modern fortran, working efficiently in parallel and so on. It is good? and for doing what? It is still good if it has a simple incompressible fluid model for only cartesian geometry and uses first order in time and space?
So, I wonder what you think about....

I have to say that, as someone who is paid to introduce features in a Fortran based CFD code, my point of view is clearly biased. But, honestly, the other possible point of view, the one of a researcher using a code to investigate the physics or the numerics, is not that far... actually the two are much closer than what is typically tought by those who have done only one of the two.

So, what this point of view is? Long story short, my personal, abstract, opinion is that a good CFD code, at least, should allow the programmer to introduce any possible new feature with an amount of work which is just proportional to the added feature and has no dependence on the previous size of the code. If, in addition, the proportionality constant remains fixed and low, independently from the task, than that is just great.

I'll give you an example. With OpenFOAM you can assemble in 5 minutes any possible physics based on scalar transport equations discretized with cell-centered, unstructured finite volume schemes. Every physics requiring something out of this scheme (e.g., a block coupled solver) just doesn't fit anymore the underlying framework and requires reworking previous pieces of code... probably weeks/months of work.

Computational efficiency might require that, for example, specific versions of some algorithms are implemented for different conditions. But this adds nothing to the reasoning. One might have 20 different routines for 20 different cases of matrix-matrix multiply, and still have them confined in a library which is completely independent from all the other pieces of code. If you modify any of them, you just change the relative calls.

So, the point is, independent pieces of code for every functionality.

The long story is that i like to think any programming task, especially those acting on previously existing pieces of code, as the task of proving a theorem within the formal system defined by the language of your choice using a set of hypotheses and previosly proved theorems within the same formal system.

With this specific approach i find extremely easy (personal opinion) to discern good and bad programming practices and how my CFD code should be organized. But, at this point, thinking about CFD is just distracting with respect to the final point, i would rather talk about a generic library (i.e., a collection of theorems with their proofs) written in the specific language of choice.

In this framework, any time you introduce useless hypotheses or theorems you don't need, you are doing a bad job. End of story.

If, to prove a new theorem, you make a previously proved theorem false... well, that is just unacceptable in this framework.

You can have different proofs of the same theorem, some of which require more or less previous theorems (i advocate, instead, that minimizing the required number of hypotheses is absolutely a good practice per se, independently from everything else), and this automatically gives you all the indications on how to organize them.

Coming to one of your examples, a structured cartesian grid as underlying data structure for a CFD code is just a weird, very restricitive, initial hypothesis. My experience says that the possible set of theorems you are going to prove with this initial hypothesis is very limited. Which, however, does't mean that they are all useless.

Thus, the only point where i see your objection coming into the picture is about what this library (i.e., the CFD code) is doing. Is this something useful? Is it worth the effort? But i don't see such questions as specifical with respect to the underlying matter here, good coding (i'll come to Fortran in a while).

Are Euclid's Elements (https://en.wikipedia.org/wiki/Euclid%27s_Elements) useful to beavers (https://en.wikipedia.org/wiki/Beaver)? Maybe not, they just need to build dams which are good enough for their purposes. But would you classify beaver dams as a scientific work or just adaptation?

I think, that the purpose of the task is totally independent from the way it is accomplished (and i hope the formal system point of view can help clarify this). And the fact that a programming task exists, by itself, automatically precludes some pieces of code from being good, no matter what they accomplish. Producing a scientifically relevant answer with a piece of code doesn't mean that the piece of code is good from the prgramming point of view (still, the scientifically relevant work obviously remains).

Obviously, there is a missing definition here of what a CFD code actually is or, better, to what input is this black box expected to produce output and how we measure the quality of the output. Again, my personal point of view is that this is the premise of the coding, not part of it. In the design phase a target is defined and, when the work is done, quality measures are applied to the CFD code output to verify that the target is reached. You can have bad and good codes which both hits the same target.

My experience also says that the choice of the target is somehow related to the set of the hypothesis underlying the framework/code, with higher standards (according to some measure) usually achievable only at the price of a larger set of fairly restrictive hypotheses. Here, the commercial point of view is quite straightforward: use state of the art methods which meet the hypotheses of the market and can pay off the implementing effort. First order and cartesian grids are thus tipically out (to answer your question).

Finally, for the Fortran part, again, i found a lot of misconceptions about it. I don't know C good enough, but i think that Fortran 2008 is already more powerful than that, with much less verbosity.

Even if it's not in the list of my favourites books (it is either badly written or too much advanced for me), this:

Scientific Software Design: The Object-Oriented Way

by Damian Rouson, has some pretty advanced examples of what Fortran can actually do. Honestly, i don't know a single scientific programmer which is so exposed to software engineering to take advance of this (and i have serious doubts also for the C++ part).

I would be glad to see some examples of C++ design patterns useful in scientific computing and which cannot be replied in Fortran.

arjun August 22, 2016 11:59

Fortan could do a lot and because of pressure from c++ there has been push to have object oriented type stuff too. Pointers even fortran 95 had if i am not wrong.

The problem with fortran in my opinion is that all these dont come naturally to it and thus its not so comfortable programming in fortran when you want to use all these concepts.

C++ also have enormous feature set and its growing. But i dont think there are many who can use this.

When I designed FVUS/Wildkatze I made lots of decisions that good c++ programmer would not make. For example I avoid templates as hell. Which is most celebrated feature of C++.

The reason is that its take a lot to compile a templated code and that means loss of efficiency in development. I also avoid polymorphism because that also later produces issues with design.

At the end though, the design allows me to rapidly add features and allow me to rapidly replace features too. I am now my third version of flow model inside. I could replace it with newer model without disturbing other models. Use of design patterns allows me to pretty much have plug and play models.

All this would be nightmare in fortran when i think about it.

atelcikti1 May 26, 2017 05:29

good programming is learning how to create data strucures and it is the hardest topic. you can look through some simple well written fortran codes that can be easily developed. su2 and openfoam are not appropriate who is new to cfd. you can easily find open source codes ie. check idolike cfd web page. moreover you can find the book that governs the equations which are coded. at first time just check the code and learn then try to develope for new algorihms with simple modules and algorithms. writing a solver is composed of discretization creating the matrix and linear system solver. focus each topic separately. and start from euler equations to understand the solution procedure of wave equations.

Sent from my SM-J710FQ using CFD Online Forum mobile app


All times are GMT -4. The time now is 06:25.