What is a good programming language for matter (e.g. molecular or materials) modeling?
Since this is a broad field, I don't expect there to be only one answer.
What is a good programming language for matter (e.g. molecular or materials) modeling?
Since this is a broad field, I don't expect there to be only one answer.
The answers above allude to what some call the "two-language problem". In materials science it takes the form of writing your code in Fortran for speed, and writing an interface to it in Python for sanity and interactivity. Fortran will not go away any time soon due to the massive amount of legacy code available. For new codes, there is a new option: Julia.
With a little bit of care (follow a few simple rules given in the "performance tips" section of the manual), one can easily mix Python-style high-level code and Fortran-style tight inner loops. Julia is easily interoperable with other languages, and reuse existing libraries (the Python interface, in particular, being particularly seamless). Coupled with a very good native ecosystem for numerical computing (unlike Python which is forced to hack together a core language not designed for numerics and NumPy), this makes it a particularly appealing language to use.
At least that has been our experience developing DFTK (https://github.com//JuliaMolSim/DFTK.jl/), a plane-wave DFT code built from scratch. The code is about one year old, ~4k LOC, and covers the basics of such codes. Had we chosen Fortran for this task, we'd still be writing the input file parser and makefile (I'm only partly joking).
A large part of materials modelling involves density functional theory and molecular mechanics. From this compilation of quantum chemistry software, the most widely used programming language seems to be Fortran.
Indeed, the popular packages VASP (commercial), Quantum Espresso and Siesta (both free) all use this language.
@taciteloquence has already mentioned Python for data analysis and visualization, but let me add one more angle: automation.
Simulation nowadays often means high-throughput, automated simulation. Not only for large scale projects, like Materials Project but also individual projects where large amounts of data generated for screening properties, screeing different geometries, generating data files for machine learning, ABC approaches etc.. For building workflows (eg with automate) or examining the generated databases, Python is good language.
I'll go first. For context: I do mostly Monte Carlo simulations, especially quantum Monte Carlo. My work has focused on spin systems, using techniques like the Metropolis Algorithm and stochastic series expansion QMC.
For Writing Simulations:
In my field there are few software packages available and the algorithms are sufficiently simple that most people write their own code from scratch. Especially for Monte Carlo, serial performance is key, memory is rarely an issue, so most people use fast, compiled languages like C/C++ or Fortran. Interpreted languages like python are often too slow for intense computations, but people do use hybrid solutions where the expensive calculations are written in C and called from python, which can be a good option.
C/C++ are great general purpose languages that you might want to learn for a whole host of reasons, and when properly optimized, they are very fast.
Fortran is less sophisticated than C/C++, but it is designed for writing simulations, so stuff like complex numbers, exponential and power functions are native. It's also very fast. In my experience, it's basically impossible to write slow Fortran code.
For Data Processing/Plotting:
After the simulations are done, you need post-processing programs to perform averages, calculate derived quantities and make figures. Here, speed is not important, so most people use an interpreted language. I personally use MATLAB (and it's GNU clone, Octave) for post-processing and plotting. MATLAB is commercial software, so the documentation is great and it works reliably on all sorts of machines. I can write scripts to fully automate plotting and they work reliably for years. The (literal) price you pay is that you have to buy a license or use one provided by your institution. Matlab can be pretty expensive.
If you're starting from scratch, it's probably a better idea to learn python. Python is a powerful, flexible language and it has a billion packages that make it pretty easy to get started on anything. There are a lot of resources for learning python and, unlike Matlab, it's free.
Okay, I have to add Julia.
Everyone is saying Fortran or Python, and I love them both, but they both have issues. Fortran is easy for a compiled language to write, but I still have SIGSEGV
burned into my retinas. Python is fast to write, but very slow. Learning how to cleverly make python fast (and it is still not all that fast) takes more time and skill than learning Fortran.
I will say, for Quantum Mechanical calculation, there are many Numpy libraries that essentially do the hard parts in C/C++/Fortran, so I will not complain about using python for Quantum Mechanics. However, if you think you as a beginner are going to write fast Python code... forget about it. You need to learn Python, as well as all of the specializations in Numpy and Scipy.
However, for atomistic simulation (molecular mechanics), there is only brute force for loops. Vectorization only gets you so much, and Python drives me crazy here.
Julia however is as easy to write as Python, as pleasant to write as Python, and, so long as you follow some simple rules, such as making sure you do not change a variables type accidently, as fast as Fortran. There are built in standard tools for helping with this such as @code_warntype
The only downside to Julia is that the bandwagon picked Python. However, that is changing. Julia is on the rise.
If you want to write a prototype, which then turns out to be just as fast as a compiled language (because it is) choose Julia.
I think one major question that needs to be asked is "What do you want to do?".
Develop new quantum chemistry codes? Use them more efficiently? Automate data processing? User @taciteloquence Has given a good answer I think. Many legacy codes are written in Fortran - newer codes will be typically written in C or C++. I believe there is also a Python project as well as a toolkit tying "things" together written in Python (The Atomic Simulation Environment). So as little as I personally like Python, it is used in the field.
To process data, you have two main approaches: Deal with the binary files or deal with the text files. I have myself written C++ code to extract and process data from text files.
If you have numerical data, it can be processed well in R. I actually started with a mix of C++ and R for extraction and processing but then gravitated to C++ only as it was faster (and I also ended up improving a lot of the underlying workflow structure). Still, I suspect my code "died" when I finished the PostDoc...
Another code I wrote (which lead to a recently published paper by a PhD student) was a C++ implementation of solvation models that existed in Fortran already. Why? It enabled "us" to optimise a model and the use of RAM for storing data lead to very significant performance increase. Oh, and I wrote the code to work with ORCA output. But in the end, your choice of post-processing language is effectively personal. Use what you like - what your colleagues can use. Be it C++, R, etc. For computation-heavy tasks, compiled languages will typically give better performance that interpreted languages. R? Lovely plot and data post processing, but loops are much slower than in C++ and the data structure is limited compared to structs/classes in C++. So basically, chose based on interest and maybe based on what the people around you use (with some qualifiers - I would argue that Excel should in many cases not be used...).
Something that wasn't touched upon by others: Automation. Learn some Bash (or another shell of your choice). My paper on fitting regression coefficients? I built the xyz geometries by hand, but then just ran the calculations using scripts. I did NOT write the input files with the methods by hand. A good scripting language will allow you to automate many mundane tasks. Once upon a time I used to write job scheduler scripts by hand... Nowadays I create a script to submit the job which I can call. I spend time figuring it out once but afterwards do not wear out my patience with menial tasks. So definitely look into scripting.
Though automation can also use more classical programming languages. If you have a set series of steps you wish to carry out. Let me given a rough example:
You run a large number of quantum chemistry calculations (optimisations and frequencies).
You use bash to extract the location of all text files
You hand the list of file paths to a C++ code that extracts the desired data from the output files into a database. This can include further tasks such as identifying non-converged geometries, transition states, etc. Your limitation for many data-processing tasks is often your own competency. And the best way to get better at it, is to gain experience.
For those interested in the papers I mentioned, I leave you with the DOIs. - In terms of tools, I was using bash, C++ and R.
10.1016/j.fluid.2020.112614
10.1002/jcc.25763
It depends on what you want to do. As a couple of others have pointed out, many of the computer programs used in computational chemistry and theoretical solid state physics are written in Fortran. However, that does not imply that you should learn Fortran and it does not mean that Fortran is the best language for materials modelling.
Even if you are concerned with writing serious code for a DFT/MD code. Consider that languages like Python and Julia are very easy to pick up. If you want to get to learn the theory and spend less time thinking about the implementation (as beginners should), it's hard to beat these languages. The other advantage that python has is that it has by far the best ecosystem surrounding modelling programs. The atomic simulation environment (ASE) has very significantly improved my productivity when working with programs like VASP.
That said, it doesn't mean that you cannot use python to contribute to serious DFT codes. the best example would be GPAW:
developing a DFT program takes a lot of time and when competitors had a headstart of decades you need ot catch up. ~80 % of GPAW are written in python and the very performance critcal parts are written in C. This allows them to regularly ship new versions with significant amounts of new features.
Furthermore python can be made very fast via numba, cython (see relevant answer) or pybind11, but it has some pitfalls. It is not as easy to implement complicated and performant, data structures in Python as it is in C++.
It should be noted that I am not saying you shouldn't learn Fortran. It is a perfectly good choice for a high performance computing language. The big problems Fortran has are that it lacks essential features of modern programming languages, like a package manager and the fact that there are essentially only very large projects. Therefore, it can be difficult to progress after you get the basics down. There are no medium sized projects one could contribute to. There are some recents efforts to make Fortran more popular again, namely https://fortran-lang.org/
At the end of the day, it depends on what you make of these languges as any of them are fine to learn.
Python is definitely a good language for scientific calculation.
The syntax is very simple. It is not hard to implement some novel method and conduct preliminary tests.
The library is abundant. One could almost do everything in python. There are many open source libraries in python that implement a variety of libraries of scientific computing and data analysis.
It is not hard to build interface with other languages. One drawback of python is its low efficiency. While there are many ways to build interface to other languages(e.g. to build python-c interface, one could use Cython (see relevant answer) or cprofile):
There are currently two answers suggesting Python (by Paulie Bao and Greg). Python is a high-level, interpreted, dynamically typed, garbage collected, and general-purpose programming language. All this means is that you can have an actually working, readable piece of code in a considerably short amount of time and that this code can do pretty much anything (from machine learning to convex optimization to parsing computational chemistry logfiles).
But coding faster does not mean fast code. This has been argued in other answers, particularly in the context of compiled (e.g. C/C++/Fortran/etc.) versus interpreted languages (such as Python, see answers by taciteloquence, Antoine Levitt, DetlevCM, Camps♦, etc.). Of course, you could try to avoid this discussion by using the many Python libraries that actually wrap C/C++/Fortran codes, such as NumPy or SciPy; this is probably fine for using Python as an (excellent) replacement for MATLAB/Octave (see this answer as well), but this might not be enough. What if we could compile Python? Better yet, what if we could only compile the bottlenecks?
Cython can be described as a C/C++-compiler for Python. You can either compile pure Python code (for which you can expect a 30-40% performance boost) or an annotated version of it (for which you might not see a difference from pure C). The good thing is that the compiled modules are fully interoperable with the Python ecosystem.
Since all simulations are CPU and memory consuming, I recommend to not use interpreted language like Java, Julia*, Python, etc.
Compiled languages are converted directly into machine code that the processor can execute. As a result, they tend to be faster and more efficient to execute than interpreted languages. They also give the developer more control over hardware aspects, like memory management and CPU usage.
More information about the advantages/disadvantages can be read here.
*Julia is not an interpreted language but uses just-in-time (JIT) compilation, implemented using LLVM. See a related answer.
Recently I watched a couple impressive talks by Christian Schafmeister, where he discusses how they actually built a full fledged Common Lisp implementation on top of LLVM, named Clasp, targeted at molecular design:
Clasp: Common Lisp using LLVM and C++ for Designing Molecules
2018 LLVM Developers’ Meeting: C. Schafmeister “Lessons Learned Implementing Common Lisp with LLVM”
Common Lisp is a dynamic language almost as old as Fortran. Among the reasons to choose it, Schafmeister cites a stable standard, proper macros and unmatched energy efficiency when compared to other dynamic languages, as shown in this table[2]:
References:
I have used bash scripts to automate materials modelling workflows. You can use online resources to learn more about bash commands and bash scripting. The idea is simple. If you have a repetitive and time-consuming task just write the terminal commands (usually run directly in the command line interface) on to a "file_name.sh" file and run it.
An example of a bash script to extract pressure, energy values from a quantum ESPRESSO output file can be found here.
I have upvoted a lot of the other answers here, and I didn't write this answer at first because most matter modeling software doesn't use it, mainly for reasons I mention below.
However, there's a lot of answers here now: not just the best or most popular languages for matter modeling, and MATLAB does have its place. You will quickly notice that I love MATLAB and will appear biased, so I will start first with the disadvantages:
python
).function H = Hamiltonian(alpha,h)
x=[0 1; 1 0 ];
y=[0 -1i; 1i 0];
z=[1 0; 0 -1];
I=eye(2);
H = alpha*kron(kron(x,x),I)+...
alpha*kron(kron(y,y),I)+...
alpha*kron(kron(I,x),x)+...
alpha*kron(kron(I,y),y)+...
h*kron(kron(I,z),I);
But the python version is longer and much more painful to write, as there's so many more unnecessary parentheses and extra symbols that need to be included:
import numpy as np
def Hamiltonian(alpha,h):
x = np.array([[0,1],[1,0]])
y = np.array([[0,-1j],[1j,0]])
z = np.array([[1,0],[0,-1]])
I = np.array([[1,0],[0,1]])
H = (alpha*np.kron(np.kron(Sx,Sx),I))
H =+ (alpha*np.kron(np.kron(Sy,Sy),I))
H =+ (alpha*np.kron(np.kron(I,Sx),Sx))
H =+ (alpha*np.kron(np.kron(I,Sy),Sy))
H =+ (h*np.kron(np.kron(I,Sz),I))
return H
The output for that example is also much clearer and prettier in MATLAB than for Python. Here's another example that came up in the past: Get 10 random integers from 6-19.
In MATLAB:
randperm(14,10)+5
In Python:
import numpy as np
np.random.choice(range(6,19), 10, replace=False)
I have not yet found an example which was the other way around, where Python could do something more neatly or easily than MATLAB. If you do know any examples, I'd love to see you add it to this "MATLAB vs Python" Git repo I made some time ago. Maybe what Python calls "broadcasting" is simpler than MATLAB's version which is bsxfun
(binary singleton expansion function), but since version 2016b this is no longer true.
p-code
which is an unreadable file, like a binary file in compiled languages, that runs the code as normal).gdb
for FORTRAN) except maybe something like the Java debugger in Dr. Java or Eclipse (I don't know if their profiler is comparably good though).