New features
* [Issue 33](https://github.com/MassimoCimmino/pygfunction/issues/33), [Issue 54](https://github.com/MassimoCimmino/pygfunction/issues/54), [Issue 85](https://github.com/MassimoCimmino/pygfunction/issues/85) - New class `gFunction` for the calculation of g-functions. The new class is a common interface to all boundary conditions and calculation methods. The new implementation of the solver reduces the memory requirements of pygfunction. The new class implements visualization features for the g-function and for heat extraction rates and borehole wall temperatures (both as a function of time and for the profiles along the borehole lengths).
* [Issue 75](https://github.com/MassimoCimmino/pygfunction/issues/75) - New module `media` with properties of brine mixtures.
* [Issue 81](https://github.com/MassimoCimmino/pygfunction/issues/81) - Added functions to find a remove duplicate boreholes.
Enhancements
* [Issue 78](https://github.com/MassimoCimmino/pygfunction/issues/78), [Issue 109](https://github.com/MassimoCimmino/pygfunction/issues/109) - Optimization of solvers for the calculation of g-functions. The finite line source (FLS) solution is now calculated using `scipy.integrate.quad_vec` which significantly improves calculation time over `scipy.integrate.quad`. The identification of similarities in the 'similarities' solver has also been refactored to identify similarities between boreholes as an intermediate step before identifying similarities between segments. The calculation time for the identification of similarities is significantly decreased.
* [Issue 94](https://github.com/MassimoCimmino/pygfunction/issues/94) - Refactor visualization functions and methods to uniformize figure styles across modules.
* [Issue 108](https://github.com/MassimoCimmino/pygfunction/issues/108) - Optimize the load aggregation algorithm of Claesson and Javed using `numpy.einsum()`.
* [Issue 112](https://github.com/MassimoCimmino/pygfunction/issues/112) - Optimization of `_BaseSolver.temporal_superposition()`. The computationally expensive for loop is replaced by a call to `numpy.einsum()`. This decreases the calculation time of large bore fields.
* [Issue 114](https://github.com/MassimoCimmino/pygfunction/issues/114) - Optimization of `_finite_line_source_integrand()`. The call to `_erfint()` is now vectorized. This decreases the number of calls by a factor 8 during integration. The calculation time of g-functions is decreased, especially for smaller bore fields.
Bug fixes
* [Issue 86](https://github.com/MassimoCimmino/pygfunction/issues/86) - Documentation is now built using Python 3 to support Python 3 features in the code.
* [Issue 103](https://github.com/MassimoCimmino/pygfunction/issues/103) - Fixed `gFunction` class to allow both builtin `float` and `numpy.floating` inputs.
* [Issue 104](https://github.com/MassimoCimmino/pygfunction/issues/104) - Raise an error if g-function is calculated with inclined boreholes. This will be supported in a later version of *pygfunction*.
Other changes
* [Issue 72](https://github.com/MassimoCimmino/pygfunction/issues/72) - Added a list of contributors to the front page. The list is managed using [all-contributors](https://github.com/all-contributors/all-contributors).
* [Issue 87](https://github.com/MassimoCimmino/pygfunction/issues/87) - Drop support for Python 2. All package requirements are updated to the latest conda version.
* [Issue 96](https://github.com/MassimoCimmino/pygfunction/issues/96) - Added a reference to the conference paper introducing pygfunction in the documentation.