# The source code of ABINIT

## Foreword

Unlike most of the other tutorials, this one is aimed towards developers. We want here to give you an insight into the internals of ABINIT. In other words, you will look at what's under the cap. Being an ABINIT user is not required, though it will help a lot. However some experience in programming is necessary if you want to take maximum benefit from this lesson. In particular, some ease with Fortran 95 will be truly welcome. Familiarity with the command line will be wonderful.

## Table of contents

- Context
- Objectives
- Tasks

- Get the source and compile the code
- Identify the subroutines to modify
- Add the new input variable and its associated routine
- Add a test to the test suite
- Create a patch for the project leader

## Context

The ABINIT package is aimed at being used by different groups of people, without mandatory control by the main contributors of the ABINIT group. In the same way, the ABINIT development project is fundamentally open to the contributions of different persons, not located in Louvain-la-neuve or Corning. De facto, these external contributors are members of the ABINIT group.

People using the code might consider adding their personal subroutines without trying to make them part of the official ABINIT package. However, this has two drawbacks for them: in subsequent versions, their modifications will not be incorporated, so that they might have to check and modify the interface for each new version; moreover, their addition is not tested by other users of the code, then some nasty bugs might remain unnoticed. Our opinion is that it would also be nicer from them to share the fruits of their coding efforts with other users of the code.

Of course, a collaborative effort has some drawbacks as well. In particular, the collaboration between distant developers should be carefully planned, since orthogonal modifications of the same piece of code by two different people at the same time is very likely to happen, generating "negative progress", i.e. a large waste of time when synchronization is to be done. It is also necessary to use a well-defined coding style, to provide test case files, and to comment the modifications and additions as much as possible, aiming at facilitating the maintenance and the future modifications.

The procedure we usually followed is described on the web site in the "How to contribute" page, in the Developer's corner section.

## Objectives

The main goals of this lesson are to provide you with a useful understanding of the source tree structure and the build process, as well as sensibilize you to the rules and procedures followed for the development of ABINIT. In the example we have chosen, we will suppose that you want to add an input variable to the code and create the corresponding subroutine. For simplicity, we will now imagine that you have designed a new exchange-correlation functional and that you want to test it with ABINIT. Here are the steps we will follow:

1. Get the source and compile the code.
2. Identify the subroutines to modify.
3. Add the new input variable and its associated routine.
4. Add a test to the test suite.
5. Create a patch for the project leader.

## Tasks

### Get the source and compile the code

There are two ways of getting the source code of ABINIT:

- directly from the web site `http://www.abinit.org/`, by downloading the tarball;
- from one of the archives, using GNU Arch.

While the first method is straightforward, the second one requires you to know how to use TLA, Thomas Lord's implementation of GNU Arch, or Bazaar, From Canonical Ltd. Although using this powerful development tool is far beyond the scope of this lesson, we feel it is worth mentioning it, as it has become the basis for the management of contributions to ABINIT. There is a comprehensive tutorial for GNU Arch on the ABINIT web site, in the Developer's corner section.

Once you have got the tarball, uncompress it by typing:

tar xvzf abinit-<version>.tar.gz

where <version> is the version number you downloaded, e.g. "5.1.2". Then go into the newly-created abinit-<version> directory and have a look at it. To get get more familiar with the source tree structure, have a closer look at the `~`ABINIT/doc/developers/dirs_and_files file You can alternatively consult it on the website (see "Developer's docs"). Then answer the following questions:

Q1. If you need off-line documentation, in which directories will you look for?

Q2. Where can be found the external libraries?

Q3. What do the numbers in the names of the "src" subdirectories stand for?

Q4. In the source subdirectories, what do the abinit.src files contain? In your opinion, what is their purpose?

Q5. What kind of tests are available? How important do you think they are?

Now you can try to build ABINIT. Information on how to do it is stored inside the INSTALL file. Please read it now.

Before actually starting the compilation, type:

./configure --help | more
and read carefully the output.

The compilation will likely take more than 10 minutes. In the meantime, you can proceed to the next task.

### Identify the subroutines to modify

At this point, you have to discover what parts of the code will have to be modified in order to have your contribution correctly integrated. Devise a strategy to establish the list of files you will have to work on. Answering the following questions should give you some hints.

Q6. How would you identify the subroutines involved in the treatment of input variables?

Q7. Where are the routines handling exchange-correlation? Which input variables are they strongly related to?

Q8. What subroutine would you choose as a parent for yours?

### Add the new input variable and its associated routine

Choose randomly a subroutine in one of the "src" subdirectories and have a look at it, putting emphasis on its header. Then read thoroughly the file `~`~abinit/doc/developers/programming_rules. This is an essential step before you start writing your own subroutine. To actually start, go to the subdirectory you've identified before and just type:

../../mkroutine handle_lesson
This will create a file named handle_lesson.F90, handle_lesson being the name of your subroutine.

For this lesson, your input variable will be a real number called "lesson". The task devoted to your routine is just to transmit the value of this input variable in a suitable format to the wrtout subroutine.

Q9. Where is wrtout? What is its purpose? How does it work?

Add treatment code for your input variable to the files you have identified previously. Then write your subroutine and add a call to it at a suitable place. Last but not least, rebuild abinis.

### Add a test to the test suite

Since your contribution is to be integrated into the 5.1 version of ABINIT, all associated tests should go to the `~`ABINIT/tests/v5/ directory. Wander a little bit around the subdirectories of tests/, and have a look at their content. Focus particularly on the README and RunTests.cnf files there. Each test is identified by an index, attributed after consulting the ABINIT Project leader. He decided that your contribution will be checked by test #100.

Q10. What do you need to do in order to have a new test added ?

Implement your test and execute the tests/Scripts/wrap-standard-tests.sh script with suitable parameters.

### Create a patch for the project leader

There are two ways of creating a patch, depending on whether you are using GNU Arch or not. If yes, you just have to register your new files, write a change log and commit your changes. This procedure is highly recommended, as it is very fast and as the project leader will be provided with a lot of flexibility and information to handle your contribution. If not, you have to create a patch with a full description of your changes and send it by email or ftp.

To get some comfort, the project leader needs a patch both in universal format and where new files are considered empty in the old version.

Q11. Which options will you give to the diff command to produce the patch ?

Q12. How will you proceed exactly to create it ?

*** Solutions will be added here ***