The `pugs` framework
====================

`pugs` stands for Parallel Unstructured Grid Solvers.

It aims at providing a collection of numerical methods and utilities
that are assembled together by a user friendly language.

# Building `pugs`

## Requirements

For the most basic build, `pugs` only requires
- a C++-20 compiler.
  - g++-10 or higher versions
  - clang-11 or higher versions
- `CMake` (at least 3.19)

> **Warning**:<br>
> Building `pugs` in its source directory is **forbidden**. Trying to
> do so will result in a failure. However it generally leaves some
> garbage files in the source directory, namely the `CMakeCache.txt`
> and the `CMakeFiles` directory. `CMake` itself is not able to remove
> them, to avoid the risk of compilation issues, one has to dot it
> manually...

In the build directory, one for instance launches
```shell
cmake path-to-pugs-source
```
and then
```shell
make -j nb_jobs
```
Specifying the compiler is done for instance as
```shell
CXX=g++ CC=gcc cmake path-to-pugs-source
```

When compilation is done, `pugs` binary is produce. Additionally, one
can run unit tests by
```shell
make check
```

## Optional packages

`pugs` can benefit from additional packages to gain more
functionalities or development tools.

### Optional numerical tools

#### MPI support

`pugs` integrates MPI support and should compile with any MPI-3
implementation. However in order to dispatch meshes on MPI processes
`pugs` requires `ParMETIS`. Without, MPI support will be automatically
deactivated.

The easiest way to enable MPI support on Debian-like systems is to run
```shell
apt install libparmetis-dev
```

#### `PETSc`

`pugs` can use `PETSc` to solve linear systems. In `pugs` the `PETSc`
support requires MPI support.

To install `PETSc` on Debian-like systems
```shell
apt install petsc-dev
```

#### `SLEPc`

`SLEPc` is an eigenvalue problem solver based on `PETSc`. It requires
`PETSc`.

To install `SLEPc` on Debian-like systems
```shell
apt install slepc-dev
```

## Documentation

### User documentation

To build documentation one requires `emacs`, `gmsh` and `gnuplot`,
additionally since examples results are generated, the documentation
can only be produced after the compilation of `pugs` itself.

To install `emacs` on Debian-like systems
```shell
apt install emacs
```
To install `gmsh` on Debian-like systems
```shell
apt install gmsh
```
To install `gnuplot` one can either use
```shell
apt install gnuplot-nox
```
or
```shell
apt install gnuplot-x11
```
> **Warning**:<br>
> When building the documentation for the first time, a local `emacs`
> configuration is generated. *This requires an internet connection.*


These packages are enough to build the html documentation. To build
the pdf documentation one requires a few more packages: `pdflatex`
(actually a fresh texlive installation is probably necessary) and `pygmentize`

On Debian-like systems these two packages are installed after
```shell
apt install texlive-full
```

Running the command
```shell
make doc
```
produces both the `html` and `pdf` documentation. Additional targets
are
- `userdoc`, `userdoc-pdf` and `userdoc-html`.

> **Warning**:<br>
> The documentation building **should not** be run in
> parallel. Generation uses similar temporary files. A generation race
> can produce corrupted documentations.

### `doxygen` documentation

## Development tools

### `clang-format`

If `clang-format` is found, a new compilation target is defined which
allows to run

```shell
make clang-format
```

This allows to run `clang-format` on the entire code. **This should
never be run** on non main development branches since `clang-format`
versions may experience unpleasant compatibility issues.

### Static analysis

#### `scan-build`

To install `scan-build`
```shell
apt install clang-tools
```
It is fairly simple to use. First launch
```shell
scan-build cmake path-to-pugs-source -DCMAKE_BUILD_TYPE=Debug
```
Observe that the code is built in debug mode to reduce false
positives.

Then compile `pugs`
```shell
scan-build make -j nb-jobs pugs
```
One can use any other generator such as `Ninja` for instance. Here we
only build `pugs`'s binary, which is generally enough.

At the end of the compilation, an hint such as
```
scan-build: Run 'scan-view /tmp/scan-build-XXXX-XX-XX-XXXXXX-XXXXX-X' to examine bug reports.
```
is produced. Running this command opens the report in the default
browser.

`scan-build` is a precious tool but may unfortunately produce false
positives.

#### `clang-tidy`

We do not give details here about `clang-tidy`. It is a much more
complex tool and should be used by more experienced developers since
it requires fine tuning and produces a lot of false positive.

#### `clazy`

`clazy` is another great static-analysis tool. It checks constructions
and gives some performances hints. It can be install by
```shell
apt install clazy
```
When `clazy` is installed a new target is defined and one just has to
run
```shell
make clazy-standalone
```

> **Warning**:<br>
> Since some generated sources files are required, one must first run
> a classic compilation in the same build directory.

This is a special homemade compilation procedure: specifying jobs has
no effect. Each file is checked serially.

## `CMake` building options

In this section we give specific options that can be used to modify
the way `pugs` is built.

### Optimization options

| Description | Variable                | Values                                  |
|:------------|:------------------------|:---------------------------------------:|
| Build type  | `CMAKE_BUILD_TYPE`      | `Release`(default), `Debug`, `Coverage` |
| OpenMP      | `Kokkos_ENABLE_OPENMP`  | `ON`(default),  `OFF`                   |
| Pthread     | `Kokkos_ENABLE_PTHREAD` | `ON`, `OFF`(default)                    |
| Serial      | `Kokkos_ENABLE_SERIAL`  | `ON`, `OFF`(default)                    |

- `Coverage` is a special compilation mode. It forces the run of unit
  tests and produces coverage reports. See below for coverage
  instructions.
- OpenMP, PThread and Serial builds are mutually exclusive. OpenMP
  support is automatically enabled as soon as the C++ compiler
  supports it.

### Additional packages support

| Description     | Variable            | Values                       |
|:----------------|:--------------------|:----------------------------:|
| MPI support     | `PUGS_ENABLE_MPI`   | `AUTO`(default), `ON`, `OFF` |
| `PETSc` support | `PUGS_ENABLE_PETSC` | `AUTO`(default), `ON`, `OFF` |
| `SLEPc` support | `PUGS_ENABLE_SLEPC` | `AUTO`(default), `ON`, `OFF` |

### Code coverage build

To enable coverage more, one requires the following tools:
- `lcov`
- `gcov`
- and `fastcov` when using `g++` as a compiler.

To install these tools
```shell
apt install lcov gcov python3-pip
```
then to install `fastcov`, as the user do
```shell
pip3 install fastcov
```

Then to get coverage reports one can do
```shell
CXX=g++ CC=gcc cmake path-to-pugs-source -DCMAKE_BUILD_TYPE=Coverage
```
and
```shell
make -j nb-jobs
```
This produces a text report summary and a detailed html report is
produced in the `coverage` directory.

One can also use `clang` but the production of the report is much
slower (does not use `fastcov`).