.. Building CHIMES
   Alexander Richings, 19th February 2020 

.. _build_label:

Building CHIMES
--------------- 

The main ``chimes`` repository includes a template Makefile that can be used to build CHIMES as a stand-alone C library. 

First, you will need to create a local ``Makefile`` from the template using ``cp Makefile_template Makefile``. You may need to edit your local copy of the ``Makefile`` for your system. In particular, if it cannot automatically locate any system-installed HDF5 and Sundials libraries (for example, if you installed your own Sundials libraries), then you will need to specify the paths to these libraries via the ``SUNDIALS_PATH``, ``HDF5_INCL_PATH`` and ``HDF5_LIB_PATH`` variables at the beginning of the Makefile.

There are also compiler flags that you can pass to the compiler via the ``CFLAGS`` variable in the Makefile:

* ``-DCHIMES_USE_DOUBLE_PRECISION`` - Build CHIMES in double precision. If you do not include this flag, CHIMES will be built in single precision. Note that you will need to ensure that the Sundials library is built with the same precision as CHIMES. For new users, we recommend using double precision. Single precision can be faster in some circumstances, but it can also be slower. In general, when integrating the chemistry over a short period of time (for example, if you are following the non-equilibrium chemical evolution in small steps), single precision tends to perform better. However, when integrating for a long period of time (~1 Gyr or more), for example if you are just evolving the system to the final equilibrium state, single precision tends to be a lot slower than double precision, as it has to sub-cycle the integration with more steps (although they both reach the same solution). If you wish to explore using single precision, you will need to test it carefully to see whether single or double is fastest for your application.
  
* ``-DCHIMES_USE_GNU_SOURCE`` - This tells CHIMES to use the GNU extensions, which will allow it to use the ``exp10()`` function that is provided by the GNU extensions. If you do not include this compiler option, CHIMES will define its own ``exp10()`` function. If you are unsure whether your system supports GNU extensions, it is best to avoid this option. 

Once you have set up the Makefile for your system, you can then build CHIMES by running:

.. code-block:: bash 

  make 

This will build the CHIMES library, ``libchimes.so``, in the root ``chimes/`` directory. 

Compiler Errors
^^^^^^^^^^^^^^^

When you build CHIMES, you may encounter an error such as the following: 

.. code-block:: bash

  ./src/chimes_cooling.c:171:26: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'cooling_rate'
    ChimesFloat * restrict cooling_rate = data.chimes_current_rates->cooling_rate; 
  ./src/chimes_cooling.c:171:26: error: 'cooling_rate' undeclared (first use in this function)

This error has been known to sometimes occur with the ``gcc`` compiler (although not always), but it may also affect other compilers. It arises because CHIMES uses the ``restrict`` keyword, which is defined as part of the C99 standard. For most compilers this should not be a problem, but if you see the above error you will need to add the ``-std=c99`` option to the ``CFLAGS`` line in the Makefile, which will make the compiler use the C99 standard. For example, if you use this option together with the GNU extensions then your ``CFLAGS`` line might look like this: 

.. code-block:: bash 

  CFLAGS = -std=c99 -DCHIMES_ENABLE_GNU_SOURCE

However, if you are not using the GNU extensions then switching on the C99 standard may lead to the following error: 

.. code-block:: bash 

  'M_LN10' undeclared 

In this case you will also need to add ``-D_XOPEN_SOURCE`` to the ``CFLAGS``, and so your ``CFLAGS`` line in the Makefile would look like this: 

.. code-block:: bash 

  CFLAGS = -std=c99 -D_XOPEN_SOURCE






