# Changelog

Versions follow [Semantic Versioning](https://semver.org/) (`<major>.<minor>.<patch>`).

Backward incompatible (breaking) changes will only be introduced in major versions
with advance notice in the **Deprecations** section of releases.


<!--
You should *NOT* be adding new changelog entries to this file, this
file is managed by towncrier. See changelog/README.md.

You *may* edit previous changelogs to fix problems like typo corrections or such.
To add a new changelog entry, please see
https://pip.pypa.io/en/latest/development/contributing/#news-entries,
noting that we use the `changelog` directory instead of news, md instead
of rst and use slightly different categories.
-->

<!-- towncrier release notes start -->

## fgen v0.6.1 (2024-10-04)


### Bug Fixes

- Fix missing header file in the f2py wrapper.
  This impacted some versions of numpy and only linux as far as we know. ([#129](https://gitlab.com/magicc/fgen/-/merge_requests/129))

### Trivial/Internal Changes

- [#129](https://gitlab.com/magicc/fgen/-/merge_requests/129)


## fgen v0.6.0 (2024-07-09)


### Breaking Changes

- Fixed the type of integrables.

  External libraries will now need to make sure that their integrable function
  has signature

  ```fortran
  function integrable(t, y)
      real(kind=8), intent(in) :: t
      real(kind=8), intent(in), dimension(:) :: y
      ! ! The line below is the one that differs
      real(kind=8), dimension(size(y)) :: integrable
  end function
  ```

  rather than the previous expected signature of

  ```fortran
  function integrable(t, y)
      real(kind=8), intent(in) :: t
      real(kind=8), intent(in), dimension(:) :: y
      ! ! The line below is the one that differs
      real(kind=8), dimension(:), allocatable :: integrable
  end function
  ```

  In other words, `real(kind=8), dimension(:), allocatable :: integrable`
  -> `real(kind=8), dimension(size(y)) :: integrable`. ([#126](https://gitlab.com/magicc/fgen/-/merge_requests/126))

### Features

- Added the ``initialise_stores`` flag to {meth}`libfgen.fgen_timeseries_builder_collection.TimeseriesBuilderCollection.add_timeseries_collection_to_stores`.

  This allows the builders' stores to be initialised at the same time as adding a {obj}`libfgen.fgen_timeseries_collection.TimeseriesCollection` to the builder collection.
  This is particularly useful when running coupled models,
  because it allows the store to be set up on the first time step
  with a call that can remain the same (except for the value of ``initialise_stores``)
  throughout all iterations. ([#128](https://gitlab.com/magicc/fgen/-/merge_requests/128))

### Bug Fixes

- Fixed the setting of `stepper % y` when using {func}`libfgen.fgen_solve_ivp.solve_ivp`.

  Previously, `stepper % y` would be interpolated between
  whatever the last value solved in the 'main' stepping
  and the value held by the stepper once `time_eval % value_last_bound` was passed.
  This has been fixed, `stepper % y` is now interpolated between
  the second last and last values
  held by the stepper once `time_eval % value_last_bound` is passed.
  In other words, the result is now interpolating between
  the last two values visited by the stepper
  rather than the last value visited by the stepper
  and wherever the 'main' integration ended
  (which could be many steps earlier and hence lead to much less accurate interpolations). ([#127](https://gitlab.com/magicc/fgen/-/merge_requests/127))

### Trivial/Internal Changes

- [#120](https://gitlab.com/magicc/fgen/-/merge_requests/120)


## fgen v0.5.1 (2024-06-26)


### Improvements

- Added information about the lines that will likely need to go in a `CMakeLists.txt` file to the logs produced by {py:func}`fgen.commands.generate.generate_command`.

  This allows the user to copy-paste into their own `CMakeLists.txt` file.
  The path prefix to include in these messages can be customised via the `--cmake-prefix` option,
  which can make it possible to produce output that can be directly copy-pasted. ([#124](https://gitlab.com/magicc/fgen/-/merge_requests/124))

### Bug Fixes

- Added the `--no-logging-setup` flag to our CLI.

  This allows the logging setup to be disabled from the CLI.
  This gives the user slightly more control over logging
  and is important for testing too
  (where we need a different logging configuration from the default).

  Full control over the logging is still an issue though,
  see https://gitlab.com/magicc/fgen/-/issues/81 for progress tracking. ([#124](https://gitlab.com/magicc/fgen/-/merge_requests/124))

### Improved Documentation

- Added command-line interface documentation. ([#125](https://gitlab.com/magicc/fgen/-/merge_requests/125))

### Trivial/Internal Changes

- [#119](https://gitlab.com/magicc/fgen/-/merge_requests/119)


## fgen v0.5.0 (2024-06-24)


### Breaking Changes

- Updated the generated Python type hint for deferred-size arrays to `npt.NDArray[np.float64]`, rather than e.g. `tuple[float, ...]` ([#122](https://gitlab.com/magicc/fgen/-/merge_requests/122))

### Features

- Added support for wrapping arrays of derived types (either as attributes or method return values)

  Move {py:meth}`fgen.fortran_parsing.FortranDataType.base_python_type` into the "public" API. ([#106](https://gitlab.com/magicc/fgen/-/merge_requests/106))
- Add an equality and inequality operator, including overload, to {obj}`libfgen.timeseries.Timeseries` and {obj}`libfgen.values_bounded.ValuesBounded`.

  Both these objects have a `equal_to` and a `not_equal_to` method as a result,
  but it is much easier to just use the operators directly
  (which works smoothly thanks to the overloading). ([#115](https://gitlab.com/magicc/fgen/-/merge_requests/115))
- Add {meth}`libfgen.timeseries_collection.TimeseriesCollection.get_timeseries_by_name`.

  This allows the user to get a {obj}`libfgen.timeseries.Timeseries`
  from a {obj}`libfgen.timeseries_collection.TimeseriesCollection`
  based on its name alone. ([#116](https://gitlab.com/magicc/fgen/-/merge_requests/116))
- Added {obj}`libfgen.fgen_timeseries_builder.TimeseriesBuilder` to facilitate building of a {obj}`libfgen.fgen_timeseries.Timeseries` bit by bit. ([#117](https://gitlab.com/magicc/fgen/-/merge_requests/117))
- Added {obj}`libfgen.fgen_timeseries_builder_collection.TimeseriesBuilderCollection` to facilitate building multiple {obj}`libfgen.fgen_timeseries.Timeseries` bit by bit within one container. ([#118](https://gitlab.com/magicc/fgen/-/merge_requests/118))
- Added a number of different utilities that will help with coupled model solving, specifically:

  * Added {func}`libfgen.fgen_array_helpers.searchsorted`. This is very similar to {func}`libfgen.fgen_utils.searchsorted` but provides more information about the result and uses tolerances to check for exact matches rather than strict equality.
  * Added {func}`libfgen.fgen_coupling.get_next_time_eval_basic`. This provides a basic function for getting the next set of times to evaluate when coupling models.
  * Added {func}`libfgen.fgen_number_comparisons.isclose`. This provides a reusable function for checking if two numbers are close.
  * Added {meth}`libfgen.fgen_time.TimeAxis.select`. This allows users to sub-select a {obj}`libfgen.fgen_utils.TimeAxis` easily and resuably.
  * Added {meth}`libfgen.fgen_timeseries_collection.TimeseriesCollection.build_from_solve_ivp_result`. This allows users to initialise a {obj}`libfgen.fgen_timeseries_collection.TimeseriesCollection` object from a {obj}`libfgen.fgen_solve_ivp.IVPSolvingResult` i.e. the results of solving an initial-value problem.

  ([#119](https://gitlab.com/magicc/fgen/-/merge_requests/119))

### Bug Fixes

- Ensure that the `enums.py` file follows the same `force` behaviour as other wrapped Python modules ([#110](https://gitlab.com/magicc/fgen/-/merge_requests/110))
- Fixed handling of methods that take an array of deferred shape as an input and return an array of deferred shape as output.

  All other types of input/output have had their test coverage improved.
  However, this is definitely an area where our testing strategy does not cover all possible paths.
  Hence, future tests and work may be needed in future. ([#123](https://gitlab.com/magicc/fgen/-/merge_requests/123))

### Trivial/Internal Changes

- [#111](https://gitlab.com/magicc/fgen/-/merge_requests/111), [#112](https://gitlab.com/magicc/fgen/-/merge_requests/112)


## fgen v0.4.1 (2024-04-10)


### Improved Documentation

- Fixed the generated changelog from the release of `v0.4.0` ([#109](https://gitlab.com/magicc/fgen/-/merge_requests/109))


## fgen v0.4.0 (2024-04-10)


### Breaking Changes

- Broke the initialisation for {obj}`fgen.models.ValueDefinition`.

  This was required to handle multi-return types.
  {obj}`fgen.models.ValueDefinition` must now be initialised
  with a {obj}`fgen.models.UnitlessValueDefinition` as part of its input. ([#44](https://gitlab.com/magicc/fgen/-/merge_requests/44))
- Move black and jinja2 to optional dependencies.

  ``pip install fgen`` will now only install the runtime dependencies
  required for `fgen_runtime`.
  For users that are not building wrappers,
  this change will have no impact.

  For downstream packages that generate wrappers,
  you now need to specify `fgen[templates]`
  as a build dependency in order to use the {mod}`fgen` package or the CLI.

  The unused `openscm-units` dependency was also removed. ([#49](https://gitlab.com/magicc/fgen/-/merge_requests/49))
- Changed the default module prefix to an empty string i.e. no prefix.

  This simplifies the reasoning related to prefixes
  and makes it much easier to use modules with a name
  that does not use the "mod\_" prefix.

  It does break the previous behaviour.
  However, these changes are all in the auto-generated wrappers,
  so should require minimal (if any) changes for users. ([#70](https://gitlab.com/magicc/fgen/-/merge_requests/70))
- Renamed {py:attr}`fgen.data_models.unitless_value.UnitlessValue.expose_to_python` to {py:attr}`fgen.data_models.unitless_value.UnitlessValue.expose_getter_to_python`.

  The flag does the same thing, but this renaming clarifies its behaviour. ([#79](https://gitlab.com/magicc/fgen/-/merge_requests/79))
- Re-structured the templates within {py:mod}`fgen`.

  {py:mod}`fgen.templator` was removed and has been moved to {py:mod}`fgen.wrapper_building`.
  This is the only user-facing change, all other changes are internal. ([#86](https://gitlab.com/magicc/fgen/-/merge_requests/86))
- Updated the `fgen generate` command-line interface so that it expects a series of yaml files rather than processing modules one at a time.

  This makes it much easier to handle dependencies between modules,
  as we have them all in memory at the same time.
  It also paves the way for improving our ability to wrap new types, for example enums
  (which require a Python definition of the enum to be written too, but only once at the package-level,
  as we can only pass integers across the Python-Fortran border).
  Such behaviour is not possible when we write the modules independently of each other.

  If you previously did e.g.

  ```sh
  fgen generate ... mod_1.yaml
  fgen generate ... mod_2.yaml
  ```

  Now you can just do

  ```sh
  fgen generate ... mod_1.yaml mod_2.yaml
  ```

  This MR also removed {py:func}`fgen.wrapper_building.process_module`},
  replacing it with {py:func}`fgen.wrapper_building.process_package`.
  If you previously did, e.g.

  ```python
  process_module(module, ...)
  ```

  As demonstrated in the tests, you can get the same behaviour with

  ```python
  process_package(Package((module,)), ...)
  ```

  ([#88](https://gitlab.com/magicc/fgen/-/merge_requests/88))
- Removed {py:attr}`fgen.data_models.module.Module.short_name` and {py:attr}`fgen.data_models.module.Module.short_name`.

  The same behaviour can be achieved by setting {py:attr}`fgen.data_models.module.Module.truncated_name`
  (and this option also provides much greater flexibility and control). ([#96](https://gitlab.com/magicc/fgen/-/merge_requests/96))

### Features

- Pin fgen==v0.3.1 via the CMake module ([#43](https://gitlab.com/magicc/fgen/-/merge_requests/43))
- Added the ability to handle fluxes as part of model output.

  This MR included a number of additional pieces of functionality to make this work:

  - `libfgen.fgen_time.TimeAxis` to support time axis handling including bounds
  - {obj}`fgen.models.MultiReturnDefinition` to handle the case
    where there are multiple return values from a function/method

  ([#44](https://gitlab.com/magicc/fgen/-/merge_requests/44))
- Added `libfgen.timeseries.Timeseries` ([#51](https://gitlab.com/magicc/fgen/-/merge_requests/51))
- Added module `fgen_interp1d` and module `fgen_array_helpers` ([#52](https://gitlab.com/magicc/fgen/-/merge_requests/52))
- Added `solve_until_end_time_bounds` argument to {func}`libfgen.fgen_ivp.solve_ivp`.

  This allows us to ensure that the model is solved up until the end of the last time step,
  rather than stopping at the start of the last time step,
  which is not helpful for creating timeseries objects etc. ([#54](https://gitlab.com/magicc/fgen/-/merge_requests/54))
- Added {meth}`libfgen.fgen_timeseries.Timeseries.integrate`
  and {meth}`libfgen.fgen_timeseries.Timeseries.differentiate`.

  Integration and differentiation are only implemented for key use cases.
  If you have a different use case, the skeleton is there
  but you will need to implement the details yourself.

  These are supported by {mod}`libfgen.fgen_integrated1d`
  and {mod}`libfgen.fgen_differentiate1d`
  and corresponding changes in the underlying 1D interpolation modules.

  This change also required splitting out
  {mod}`libfgen.fgen_interp1d_options` to avoid circular dependencies. ([#55](https://gitlab.com/magicc/fgen/-/merge_requests/55))
- Added {class}`libfgen.fgen_values_bounded.ValuesBounded` ([#57](https://gitlab.com/magicc/fgen/-/merge_requests/57))
- Added {meth}`libfgen.fgen_timeseries.Timeseries.get_value_at_time`
  to facilitate retrieving values at specific times.

  This also required adding {mod}`libfgen.fgen_boundary1d`,
  to support handling of the logic around
  which values to supply when on the boundary of our timesteps
  (which varies depending on the kind of interpolation which is being assumed). ([#59](https://gitlab.com/magicc/fgen/-/merge_requests/59))
- Added {meth}`libfgen.fgen_timeseries.Timeseries.interpolate`,
  {meth}`libfgen.fgen_timeseries.Timeseries.interpolate_single`
  and {meth}`libfgen.fgen_timeseries.Timeseries.extrapolat_single`
  to support interpolation and extrapolation operations
  with {class}`libfgen.fgen_timeseries.Timeseries`. ([#60](https://gitlab.com/magicc/fgen/-/merge_requests/60))
- Added support for wrapping derived type attributes which are character arrays in Fortran, str in Python. ([#71](https://gitlab.com/magicc/fgen/-/merge_requests/71))
- Added setters for and the ability for methods to return the following types:

  - intrinsic
      - float
      - int
      - boolean
  - characters/strings
      - fixed-length
      - allocatable-length
  - arrays
      - fixed-length
      - allocatable-length
  - derived types
      - accessed via pointers
      - encapsulate i.e. allocatable attributes are not yet supported,
        that will happen in #42

  The setters are not added automatically,
  they must be opted into on a per-attribute basis
  by setting `expose_setter_to_python: true`.

  ([#79](https://gitlab.com/magicc/fgen/-/merge_requests/79))
- Added support for wrapping derived types that have allocatable, other derived types as attributes ([#80](https://gitlab.com/magicc/fgen/-/merge_requests/80))
- Added support for wrapping `libfgen.fgen_values_bounded.ValuesBounded`.

  The more general pattern is that we can now support things
  that should retrieve their units dynamically from Pint quantities,
  rather than forcing all unit specifications to be static.
  There are now quite a lot of moving parts in our wrapper generation.
  We aim to clean these up as part of
  [#60](https://gitlab.com/magicc/fgen/-/issues/60). ([#81](https://gitlab.com/magicc/fgen/-/merge_requests/81))
- Added {py:class}`fgen.data_models.Package` for handling a collection of modules i.e. a package ([#88](https://gitlab.com/magicc/fgen/-/merge_requests/88))
- Added auto-generation of `_repr_pretty_` and `_repr_html_` methods to the generated Python wrappers ([#91](https://gitlab.com/magicc/fgen/-/merge_requests/91))
- Added {py:class}`fgen.data_models.package_shared_elements.PackageSharedElements` to provide a common source for elements that are common across the wrappers in a package
  and added {py:attr}`fgen.data_models.unitless_value.is_fortran_units_holder` to support and clarify how dynamic units are handled.

  {py:attr}`fgen.data_models.unitless_value.is_fortran_units_holder`
  allows you to specify that this attribute is the attribute which holds the units in Fortran,
  i.e. it is where dynamic units should be passed into Fortran
  and where dynamic units should be retrieved from Fortran. ([#93](https://gitlab.com/magicc/fgen/-/merge_requests/93))
- Added support for wrapping enums defined in Fortran.

  This was done by adding {py:class}`fgen.wrapping_strategies.enum.WrappingStrategyEnum`,
  {py:class}`fgen.data_models.EnumDefiningModule`,
  {py:mod}`fgen.data_models.enum_defining_module`
  and updating the `fgen generate` command to support taking in enum-defining yaml files.
  The changes to `fgen generate` are backwards-compatible hence require no interaction
  from users who do not wish to take advantage of this new feature. ([#103](https://gitlab.com/magicc/fgen/-/merge_requests/103))

### Improvements

- Upgraded `fgen` so it can now wrap Fortran callables that return values in different units.

  For example, a callable that returns temperature in kelvin and ocean heat
  uptake in joules per year.

  This required adding {meth}`fgen.models.CalculatorDefinition.units_str` and
  {meth}`fgen.models.CalculatorDefinition.units_multi_return`. ([#44](https://gitlab.com/magicc/fgen/-/merge_requests/44))
- Updated the codebase to handle the introduction of {class}`libfgen.fgen_values_bounded.ValuesBounded`.

  Specifically, updated {class}`libfgen.fgen_time.TimeAxis`
  so that it is a sub-class of {class}`libfgen.fgen_values_bounded.ValuesBounded`.
  (There doesn't seem to be a better way to do this in Fortran
  given the lack of attrs-style validators.)

  Also updated {class}`libfgen.fgen_timeseries.Timeseries`
  and {func}`libfgen.fgen_ivp.solve_ivp`
  to use {class}`libfgen.fgen_values_bounded.ValuesBounded`.

  Also updated {meth}`libfgen.fgen_values_bounded.ValuesBounded.repr`
  so that it can be indented in {meth}`libfgen.fgen_timeseries.Timeseries.repr`. ([#56](https://gitlab.com/magicc/fgen/-/merge_requests/56))
- Added sane defaults to format strings in {mod}`libfgen.fgen_char_conversions`.

  As a result, you no longer need to pass format strings
  into the various formatting functions in {mod}`libfgen.fgen_char_conversions`.

  Also exposed constants in {mod}`libfgen.fgen_char_conversions`
  that can be used by other components if they wish.
  We expected this would be used rarely,
  but it avoids completely hard-coding the values with no explanation of what they are
  and provides a way to control them
  without exposing arguments to control these values in every single function
  that does any character handling. ([#57](https://gitlab.com/magicc/fgen/-/merge_requests/57))
- Clarified the one-dimensional handling module.

  There is now an extensive docstring at the top of {mod}`libfgen.fgen_1d_handling_options`.

  This also included the following clean ups:

  - renaming `src/libfgen/interp1d` to `src/libfgen/1d_handling`
  - unification of the filenames in `src/libfgen/1d_handling`
  - unification of the module names in `src/libfgen/1d_handling`
  - unification of the option names in {mod}`libfgen.fgen_1d_handling_options`
  - using `time` rather than `x` consistently throughout
    {mod}`libfgen.fgen_1d_handling_options`,
    to reflect the fact that our x-axis is assumed to be a time axis
    (i.e. stricly monotonically increasing)

  As the affected features are unreleased,
  we do not provide a more detailed migration guide.

  ([#61](https://gitlab.com/magicc/fgen/-/merge_requests/61))
- Updated {func}`libfgen.fgen_ivp.solve_ivp` so it only supports the use of `t_eval`.

  `t_eval` is now a required argument
  and support for simply solving until `t_max` has been removed.
  The `t_tolerance` argument was also removed
  because the results will match `t_eval`
  so there is no need to worry about tolerance anymore.

  As the affected features are unreleased,
  we do not provide a more detailed migration guide.
  The short story is this:
  any use of {func}`libfgen.fgen_ivp.solve_ivp`
  will now require `t_eval`.
  To get the same behaviour as previously,
  set the only value in `t_eval % values`
  equal to your previous `t_max`.
  Then just drop the first value in your result. ([#62](https://gitlab.com/magicc/fgen/-/merge_requests/62))
- Re-named solver to stepper throughout the code,
  whenever the thing being referred to was an object used for
  numerically solving ODE's.

  This is a breaking change.
  For example, we have renamed `src/libfgen/solvers` to `src/libfgen/steppers`
  and renamed `libfgen.fgen_ivp` to `libfgen.fgen_solve_ivp`.
  However, as the code it breaks has not yet been released,
  we do not label this as breaking
  nor do we provide a detailed migration guide. ([#65](https://gitlab.com/magicc/fgen/-/merge_requests/65))
- Aligned the names in fgen with the domain model described in {ref}`overview-reference`.

  This is a breaking change.
  For example, we have renamed `src/libfgen/models` to `src/libfgen/data_models`
  and renamed calculator to fortran derived type throughout the code.
  However, as the code it breaks has not yet been released,
  we do not label this as breaking
  nor do we provide a detailed migration guide. ([#67](https://gitlab.com/magicc/fgen/-/merge_requests/67))
- Renamed the classes in {mod}`fgen.data_models` for consistency.

  Changes:

  - {class}`fgen.data_models.MethodDefinition` -> {class}`fgen.data_models.Method`
  - {class}`fgen.data_models.ModuleDefinition` -> {class}`fgen.data_models.Module`
  - {class}`fgen.data_models.MultiReturnDefinition` -> {class}`fgen.data_models.MultiReturn`
  - {class}`fgen.data_models.ValueDefinition` -> {class}`fgen.data_models.Value`
  - {class}`fgen.data_models.UnitlessValueDefinition` -> {class}`fgen.data_models.UnitlessValue`

  As the code it breaks was not released at the time of merging,
  we do not label this as breaking
  nor do we provide a detailed migration guide.

  ([#72](https://gitlab.com/magicc/fgen/-/merge_requests/72))
- Re-wrote {mod}`fgen.templator` and the associated template files

  Key changes:

  - wrote docs explaining how our templating works
  - made the Fortran wrapper module template and Python wrapper module template more symmetric,
    this makes it easier to see how they work
  - split the templates out into a number of smaller files.
    This means there is more to keep track of,
    but the logic is much easier to follow within the limited scopes.
  - cleaned up the templates
  - changed the naming in the templates to try to use most significant bit naming,
    e.g. wrapper modules are now `module_name_w` rather than `w_module_name`
    because the key thing is the module that is being wrapped,
    then the fact that it is a wrapper.
    This also makes the names of our modules more consistent
    (you end up with `module_name`, `module_name_w` and `module_name_manager`
    rather than having prefixes which makes it harder to line things up).

  As the code it breaks has not yet been released,
  we do not label this as breaking
  nor do we provide a detailed migration guide.

  ([#76](https://gitlab.com/magicc/fgen/-/merge_requests/76))
- Increased the number of available Fortran instances in manager modules to 4096
  and improved the validation and handling of dynamic unit values.

  In testing in the notebook, we found that you can hit 2048 easily once you start making lots of plots
  (which can trigger recursive calls to access units, with associated instance usage). ([#93](https://gitlab.com/magicc/fgen/-/merge_requests/93))
- When processing a package, generate a `__init__.py` file in the python directory
  if one does not already exist. This ensures that the Python directory is always
  a valid Python package. ([#101](https://gitlab.com/magicc/fgen/-/merge_requests/101))

### Bug Fixes

- Fixed handling of indentation when creating Python code.

  In yaml files, use "|" after multi-wrap lines
  and then things should just work from there. ([#44](https://gitlab.com/magicc/fgen/-/merge_requests/44))
- Removed unused dependency "cmakelang" from the list of dependencies. It remains as a development dependency. ([#50](https://gitlab.com/magicc/fgen/-/merge_requests/50))

### Improved Documentation

- Added documentation to clarify the domain model of fgen and the naming choices that follow.

  The code changes required to match this documentation will be done as part of solving the following issues:

  - [https://gitlab.com/magicc/fgen/-/issues/52](https://gitlab.com/magicc/fgen/-/issues/52)
  - [https://gitlab.com/magicc/fgen/-/issues/53](https://gitlab.com/magicc/fgen/-/issues/53)
  - [https://gitlab.com/magicc/fgen/-/issues/54](https://gitlab.com/magicc/fgen/-/issues/54)

  ([#64](https://gitlab.com/magicc/fgen/-/merge_requests/64))
- Added documentation explaining how our templating works.

  This sets out the patterns and strategies we use.

  At the time of merging, this is an intended goal rather than actually being how it works.
  We will update the docs over time as we do the implementation. ([#85](https://gitlab.com/magicc/fgen/-/merge_requests/85))
- Wrote docs describing how are wrapper builders and strategies will fit together. ([#88](https://gitlab.com/magicc/fgen/-/merge_requests/88))

### Trivial/Internal Changes

- [#44](https://gitlab.com/magicc/fgen/-/merge_requests/44), [#54](https://gitlab.com/magicc/fgen/-/merge_requests/54), [#58](https://gitlab.com/magicc/fgen/-/merge_requests/58), [#60](https://gitlab.com/magicc/fgen/-/merge_requests/60), [#62](https://gitlab.com/magicc/fgen/-/merge_requests/62), [#66](https://gitlab.com/magicc/fgen/-/merge_requests/66), [#77](https://gitlab.com/magicc/fgen/-/merge_requests/77), [#78](https://gitlab.com/magicc/fgen/-/merge_requests/78), [#82](https://gitlab.com/magicc/fgen/-/merge_requests/82), [#89](https://gitlab.com/magicc/fgen/-/merge_requests/89), [#90](https://gitlab.com/magicc/fgen/-/merge_requests/90), [#91](https://gitlab.com/magicc/fgen/-/merge_requests/91), [#92](https://gitlab.com/magicc/fgen/-/merge_requests/92), [#94](https://gitlab.com/magicc/fgen/-/merge_requests/94), [#95](https://gitlab.com/magicc/fgen/-/merge_requests/95), [#97](https://gitlab.com/magicc/fgen/-/merge_requests/97), [#98](https://gitlab.com/magicc/fgen/-/merge_requests/98), [#99](https://gitlab.com/magicc/fgen/-/merge_requests/99), [#102](https://gitlab.com/magicc/fgen/-/merge_requests/102), [#104](https://gitlab.com/magicc/fgen/-/merge_requests/104), [#107](https://gitlab.com/magicc/fgen/-/merge_requests/107)


## fgen v0.3.1 (2024-01-25)


### Improvements

- Add support for installing the fortran library via CMake ([#41](https://gitlab.com/magicc/fgen/-/merge_requests/41))

### Improved Documentation

- Added notebooks about subtleties of solving models in terms of input interpolation and flux handling ([#40](https://gitlab.com/magicc/fgen/-/merge_requests/40))

### Trivial/Internal Changes

- [#42](https://gitlab.com/magicc/fgen/-/merge_requests/42)


## fgen v0.3.0 (2024-01-19)


### Features

- Add colour to logging and switch to [loguru](https://loguru.readthedocs.io/) for internal logging handling ([#23](https://gitlab.com/magicc/fgen/-/merge_requests/23))
- Add `searchsorted` and `is_monotonic` functions to the `fgen_utils` module ([#30](https://gitlab.com/magicc/fgen/-/merge_requests/30))
- Add support for evaluating an initial-value problem IVP on specified timesteps via the `t_eval` parameter to `fgen_ivp.solve_ivp` ([#34](https://gitlab.com/magicc/fgen/-/merge_requests/34))
- Added basic conversions to character types (see `fgen_char_conversions`) ([#37](https://gitlab.com/magicc/fgen/-/merge_requests/37))
- Added a Euler forward solver (see `fgen_euler_forward`) ([#38](https://gitlab.com/magicc/fgen/-/merge_requests/38))

### Improvements

- Adds Fortran-based unit tests using the [test-drive](https://github.com/fortran-lang/test-drive) framework ([#21](https://gitlab.com/magicc/fgen/-/merge_requests/21))
- Added writing of `__str__` method on generated classes to provide a quick way to get more information about the Fortran values from Python ([#24](https://gitlab.com/magicc/fgen/-/merge_requests/24))
- Introduce {class}`fgen_runtime.exceptions.PointerArrayConversionError` to provide more specific context when the error raised is related to conversion from a pointer to an array.

  This context is then used to provide more information when creating a generated object's `__str__` representation. ([#26](https://gitlab.com/magicc/fgen/-/merge_requests/26))

### Bug Fixes

- Resolved the incorrect calculation of the initial step size for the rk4 solver alongside some
  refactoring that aimed to improve the readability of `solve_ivp`. ([#29](https://gitlab.com/magicc/fgen/-/merge_requests/29))
- Fixed bugs leftover from [!34](https://gitlab.com/magicc/fgen/-/merge_requests/34)

  Bugs relate to stopping conditions when solving and correctly handling t_eval steps. ([#37](https://gitlab.com/magicc/fgen/-/merge_requests/37))

### Trivial/Internal Changes

- [#31](https://gitlab.com/magicc/fgen/-/merge_requests/31), [#39](https://gitlab.com/magicc/fgen/-/merge_requests/39)


## fgen v0.2.1 (2023-12-07)


### Bug Fixes

- Wrapping of a class with more than one method (previously the methods would not have a newline between them so the generated code was not syntactically correct) ([#22](https://gitlab.com/magicc/fgen/-/merge_requests/22))


## fgen v0.2.0 (2023-12-06)


### Breaking Changes

- Refactor the fortran data type parsing module to extract additional information about a fortran type. While
  this change is breaking to the API of `fgen`, it doesn't impact the generated wrappers. ([#9](https://gitlab.com/magicc/fgen/-/merge_requests/9))
- Updates to names to better reflect the part of the Fortran specification that are being captured:

  - `fgen.fortran_parsing.SUPPORTED_TYPE_DECLARATION` --> `fgen.fortran_parsing.SUPPORTED_TYPE_SPECIFICATIONS`
  - `fgen.fortran_parsing.SUPPORTED_TYPE_ATTRIBUTES` --> `fgen.fortran_parsing.SUPPORTED_ATTRIBUTE_SPECIFICATIONS`
  - `fgen.fortran_parsing.FortranDataType.type_declaration` -> `fgen.fortran_parsing.FortranDataType.type_specification`
  - `fgen.fortran_parsing.FortranDataType.attributes` -> `fgen.fortran_parsing.FortranDataType.attribute_specifications`
  - `fgen.fortran_parsing.FortranDataType.fortran_type` -> `fgen.fortran_parsing.FortranDataType.fortran_type_attribute_declaration`
  - `fgen.fortran_parsing.FortranDataType.DimensionAttribute` -> `fgen.fortran_parsing.FortranDataType.DimensionAttributeSpecification`
  - In `fgen.fortran_parsing.FortranDataType.from_str`, keyword argument `fortran_type_declaration` -> `fortran_type_attribute_declaration`

  ([#11](https://gitlab.com/magicc/fgen/-/merge_requests/11))
- Improve typing offered by `fgen_runtime.verify_units`

  `fgen_runtime.verify_units` will now correctly type the functions it decorates,
  for example making clear that a function which receives a float will now
  expect a {obj}`pint.Quantity` as a result of being decorated. This type
  hinting isn't perfect and may break, please raise an issue if it does.

  As part of this change, we have also removed `fgen_runtime.units.Quantity`.
  Please get the class from Pint instead via e.g.
  `pint.registry.UnitRegsitry.Quantity` (or `ur.Quantity` if you already have a
  unit registry object instantiated, this is likely the better chance at
  runtime).

  The code generated by `fgen` has also been updated to match this new typing
  capability. This also caused changes to `fgen`'s API.
  `FortranDataType.equivalent_python_type` will now return float and int
  for the Fortran real and integer types rather than Quantity as was previously
  the case. ([#20](https://gitlab.com/magicc/fgen/-/merge_requests/20))

### Features

- Adds the option to reference another calculator in a wrapped function.

  `f2py` cannot directly wrap a Fortran derived type, preventing the direct passing or returning of calculators
  by value in any wrapped functions. Instead, `fgen` can pass the model index of a calculator, which
  the Python module can then convert into a concrete instance. A working example can be found in the
  `derived_type` example.

  This also adds the concept of `links` to module configuration. These links describe other wrapped modules
  that are dependencies. ([#12](https://gitlab.com/magicc/fgen/-/merge_requests/12))
- Support deferred shape arrays being used as calculator attributes ([#15](https://gitlab.com/magicc/fgen/-/merge_requests/15))

### Improvements

- Added `get_instance` subroutine to the manager modules. This allows for calculators to be referenced by pointers that
  can be retrieved using the `model_index` of the calculator. ([#6](https://gitlab.com/magicc/fgen/-/merge_requests/6))
- Add support for type hints ([#7](https://gitlab.com/magicc/fgen/-/merge_requests/7))
- Add a check to see if a valid model index was found ([#8](https://gitlab.com/magicc/fgen/-/merge_requests/8))
- Generated code now also passes ruff's [TRY003](https://docs.astral.sh/ruff/rules/raise-vanilla-args/) rule ([#17](https://gitlab.com/magicc/fgen/-/merge_requests/17))
- Fix up order of imports in generated Python and add type hints to ``_UNITS`` ([#18](https://gitlab.com/magicc/fgen/-/merge_requests/18))

### Improved Documentation

- Updated documentation throughout `fgen.fortran_parsing` ([#11](https://gitlab.com/magicc/fgen/-/merge_requests/11))

### Trivial/Internal Changes

- [#10](https://gitlab.com/magicc/fgen/-/merge_requests/10), [#13](https://gitlab.com/magicc/fgen/-/merge_requests/13), [#14](https://gitlab.com/magicc/fgen/-/merge_requests/14), [#18](https://gitlab.com/magicc/fgen/-/merge_requests/18), [#20](https://gitlab.com/magicc/fgen/-/merge_requests/20)


## fgen v0.1.2 (2023-07-17)


### Features

- Add `fgen.f2py` which wraps `numpy.f2py`, but applies some additional error handling ([#5](https://gitlab.com/magicc/fgen/-/merge_requests/5))


## fgen v0.1.1 (2023-07-14)


### Improvements

- Add support for Python v3.9 ([#3](https://gitlab.com/magicc/fgen/-/merge_requests/3))

### Improved Documentation

- Migrate to using [towncrier](https://github.com/twisted/towncrier) for managing the changelog ([#4](https://gitlab.com/magicc/fgen/-/merge_requests/4))


## fgen v0.1.0 (2023-07-03)


### Feature

- Initial release
