.. _packaging:

Create your own Snek5000 solver, packaging your Nek5000 user source code
========================================================================

This document describes how to package a Nek5000 source code in your own
repository via ``snek5000``'s API. What is described is the bare minimum to
get started.  Assume your files are named ``canonical.usr``, ``canonical.par``
etc. and you wish to package it under a name say ``snek5000_canonical``.

.. note::
   The package name does not have to contain ``snek5000`` or ``canonical``. It
   could be anything. Make sure the ``short_name`` variable (in
   :ref:`__init__.py <init.py>`) and entry point key (in setup.cfg_) matches.

One first has to create a directory structure, (preferably in a git / mercurial
repository) like this::

   .
   ├── LICENSE
   ├── README.md
   ├── setup.cfg
   ├── setup.py
   └── src
       └── snek5000_canonical
           ├── Snakefile
           ├── __init__.py
           ├── canonical.usr.f
           ├── output.py
           ├── solver.py
           └── templates
               └── __init__.py

You can copy the directory `docs/examples/snek5000-canonical
<https://github.com/snek5000/snek5000/tree/main/docs/examples/snek5000-canonical>`_
from the Snek5000 repository, and then modify the directory names and the files
as needed.

.. note::

   The Nek5000 ``.usr`` files have to contain Fortran 77 code in strict form
   layout. In snek5000 solvers, one can rename this file with the ``.usr.f``
   extension so that editors can correctly highlight the Fortran code.

setup.py
--------

.. literalinclude:: examples/snek5000-canonical/setup.py

.. _setup.cfg:

setup.cfg
---------

.. literalinclude:: examples/snek5000-canonical/setup.cfg
   :language: cfg

.. _init.py:

src/snek5000_canonical/__init__.py
----------------------------------

.. literalinclude:: examples/snek5000-canonical/src/snek5000_canonical/__init__.py

.. _solver.py:

src/snek5000_canonical/solver.py
--------------------------------

.. literalinclude:: examples/snek5000-canonical/src/snek5000_canonical/solver.py

.. note::

   As you might have guessed all additional files except for Fortran code can
   be generated by snek5000 and need not be packaged. See
   :class:`snek5000.operators.Operators` and
   :class:`snek5000.solvers.kth.SimulKTH` to see how to set the ``params``
   instead.

src/snek5000_canonical/output.py
--------------------------------

.. literalinclude:: examples/snek5000-canonical/src/snek5000_canonical/output.py

.. note::

   One can also define your own Jinja templates or re-purpose them from
   :mod:`snek5000.resources`. See our `How to page on templates
   <./how-to/templates.html>`__.

src/snek5000_canonical/phys_fields.py
-------------------------------------

Optionally, add classes for ``reader`` and ``phys_fields`` objects which would
allow customized ``load``, ``get_var`` and ``plot_*`` methods suited for your
case.

.. literalinclude:: examples/snek5000-canonical/src/snek5000_canonical/phys_fields.py

.. _user_snakefile:

src/snek5000_canonical/Snakefile
--------------------------------

.. literalinclude:: examples/snek5000-canonical/src/snek5000_canonical/Snakefile
