From db98b3887dcdcbfd9ea15663e5654d6008148aa8 Mon Sep 17 00:00:00 2001
From: Jan H <Jan.Habscheid@web.de>
Date: Sat, 2 Nov 2024 23:24:34 +0100
Subject: [PATCH] First version for a python package

---
 .eggs/README.txt                              |   6 +
 .../EGG-INFO/LICENSE                          |  19 +
 .../EGG-INFO/PKG-INFO                         | 185 ++++++++
 .../EGG-INFO/RECORD                           |   7 +
 .../EGG-INFO/WHEEL                            |   5 +
 .../EGG-INFO/entry_points.txt                 |   3 +
 .../EGG-INFO/requires.txt                     |  17 +
 .../EGG-INFO/top_level.txt                    |   1 +
 .../ptr/__init__.py                           | 216 +++++++++
 BscElectrolyteModels.egg-info/PKG-INFO        | 117 +++++
 BscElectrolyteModels.egg-info/SOURCES.txt     |  23 +
 .../dependency_links.txt                      |   1 +
 .../entry_points.txt                          |   2 +
 BscElectrolyteModels.egg-info/requires.txt    |  23 +
 BscElectrolyteModels.egg-info/top_level.txt   |   1 +
 BscElectrolyteModels.egg-info/zip-safe        |   1 +
 README.md                                     |   2 +-
 .../ElectrolyticDiode.py                      | 401 +++++++++++++++++
 build/lib/Bsc-ElectrolyteModels/Eq02.py       | 309 +++++++++++++
 build/lib/Bsc-ElectrolyteModels/Eq04.py       | 358 +++++++++++++++
 build/lib/Bsc-ElectrolyteModels/EqN.py        | 324 ++++++++++++++
 .../Helper_DoubleLayerCapacity.py             | 411 ++++++++++++++++++
 build/lib/Bsc-ElectrolyteModels/__init__.py   |   0
 .../BscElectrolyteModels-1.0-py3-none-any.whl | Bin 0 -> 35361 bytes
 pyproject.toml                                |   3 +
 setup.cfg                                     |  47 ++
 setup.py                                      |  22 +
 tests/__pycache__/__init__.cpython-312.pyc    | Bin 160 -> 127 bytes
 ...trolyticDiode.cpython-312-pytest-8.3.3.pyc | Bin 18642 -> 18609 bytes
 .../test_Eq02.cpython-312-pytest-8.3.3.pyc    | Bin 18528 -> 18495 bytes
 .../test_Eq04.cpython-312-pytest-8.3.3.pyc    | Bin 18528 -> 18495 bytes
 .../test_EqN.cpython-312-pytest-8.3.3.pyc     | Bin 10394 -> 10361 bytes
 ...LayerCapacity.cpython-312-pytest-8.3.3.pyc | Bin 31242 -> 31185 bytes
 33 files changed, 2503 insertions(+), 1 deletion(-)
 create mode 100644 .eggs/README.txt
 create mode 100644 .eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/LICENSE
 create mode 100644 .eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/PKG-INFO
 create mode 100644 .eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/RECORD
 create mode 100644 .eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/WHEEL
 create mode 100644 .eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/entry_points.txt
 create mode 100644 .eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/requires.txt
 create mode 100644 .eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/top_level.txt
 create mode 100644 .eggs/pytest_runner-6.0.1-py3.12.egg/ptr/__init__.py
 create mode 100644 BscElectrolyteModels.egg-info/PKG-INFO
 create mode 100644 BscElectrolyteModels.egg-info/SOURCES.txt
 create mode 100644 BscElectrolyteModels.egg-info/dependency_links.txt
 create mode 100644 BscElectrolyteModels.egg-info/entry_points.txt
 create mode 100644 BscElectrolyteModels.egg-info/requires.txt
 create mode 100644 BscElectrolyteModels.egg-info/top_level.txt
 create mode 100644 BscElectrolyteModels.egg-info/zip-safe
 create mode 100644 build/lib/Bsc-ElectrolyteModels/ElectrolyticDiode.py
 create mode 100644 build/lib/Bsc-ElectrolyteModels/Eq02.py
 create mode 100644 build/lib/Bsc-ElectrolyteModels/Eq04.py
 create mode 100644 build/lib/Bsc-ElectrolyteModels/EqN.py
 create mode 100644 build/lib/Bsc-ElectrolyteModels/Helper_DoubleLayerCapacity.py
 create mode 100644 build/lib/Bsc-ElectrolyteModels/__init__.py
 create mode 100644 dist/BscElectrolyteModels-1.0-py3-none-any.whl
 create mode 100644 pyproject.toml
 create mode 100644 setup.cfg
 create mode 100644 setup.py

diff --git a/.eggs/README.txt b/.eggs/README.txt
new file mode 100644
index 0000000..5d01668
--- /dev/null
+++ b/.eggs/README.txt
@@ -0,0 +1,6 @@
+This directory contains eggs that were downloaded by setuptools to build, test, and run plug-ins.
+
+This directory caches those eggs to prevent repeated downloads.
+
+However, it is safe to delete this directory.
+
diff --git a/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/LICENSE b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/LICENSE
new file mode 100644
index 0000000..353924b
--- /dev/null
+++ b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/LICENSE
@@ -0,0 +1,19 @@
+Copyright Jason R. Coombs
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
diff --git a/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/PKG-INFO b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/PKG-INFO
new file mode 100644
index 0000000..75c36d6
--- /dev/null
+++ b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/PKG-INFO
@@ -0,0 +1,185 @@
+Metadata-Version: 2.1
+Name: pytest-runner
+Version: 6.0.1
+Summary: Invoke py.test as distutils command with dependency resolution
+Home-page: https://github.com/pytest-dev/pytest-runner/
+Author: Jason R. Coombs
+Author-email: jaraco@jaraco.com
+Classifier: Development Status :: 7 - Inactive
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Framework :: Pytest
+Requires-Python: >=3.7
+License-File: LICENSE
+Provides-Extra: docs
+Requires-Dist: sphinx ; extra == 'docs'
+Requires-Dist: jaraco.packaging >=9 ; extra == 'docs'
+Requires-Dist: rst.linker >=1.9 ; extra == 'docs'
+Requires-Dist: jaraco.tidelift >=1.4 ; extra == 'docs'
+Provides-Extra: testing
+Requires-Dist: pytest >=6 ; extra == 'testing'
+Requires-Dist: pytest-checkdocs >=2.4 ; extra == 'testing'
+Requires-Dist: pytest-flake8 ; extra == 'testing'
+Requires-Dist: pytest-cov ; extra == 'testing'
+Requires-Dist: pytest-enabler >=1.0.1 ; extra == 'testing'
+Requires-Dist: pytest-virtualenv ; extra == 'testing'
+Requires-Dist: types-setuptools ; extra == 'testing'
+Requires-Dist: pytest-black >=0.3.7 ; (platform_python_implementation != "PyPy") and extra == 'testing'
+Requires-Dist: pytest-mypy >=0.9.1 ; (platform_python_implementation != "PyPy") and extra == 'testing'
+
+.. image:: https://img.shields.io/pypi/v/pytest-runner.svg
+   :target: `PyPI link`_
+
+.. image:: https://img.shields.io/pypi/pyversions/pytest-runner.svg
+   :target: `PyPI link`_
+
+.. _PyPI link: https://pypi.org/project/pytest-runner
+
+.. image:: https://github.com/pytest-dev/pytest-runner/workflows/tests/badge.svg
+   :target: https://github.com/pytest-dev/pytest-runner/actions?query=workflow%3A%22tests%22
+   :alt: tests
+
+.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
+   :target: https://github.com/psf/black
+   :alt: Code style: Black
+
+.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest
+..    :target: https://skeleton.readthedocs.io/en/latest/?badge=latest
+
+.. image:: https://img.shields.io/badge/skeleton-2022-informational
+   :target: https://blog.jaraco.com/skeleton
+
+.. image:: https://tidelift.com/badges/package/pypi/pytest-runner
+   :target: https://tidelift.com/subscription/pkg/pypi-pytest-runner?utm_source=pypi-pytest-runner&utm_medium=readme
+
+Setup scripts can use pytest-runner to add setup.py test support for pytest
+runner.
+
+Deprecation Notice
+==================
+
+pytest-runner depends on deprecated features of setuptools and relies on features that break security
+mechanisms in pip. For example 'setup_requires' and 'tests_require' bypass ``pip --require-hashes``.
+See also `pypa/setuptools#1684 <https://github.com/pypa/setuptools/issues/1684>`_.
+
+It is recommended that you:
+
+- Remove ``'pytest-runner'`` from your ``setup_requires``, preferably removing the ``setup_requires`` option.
+- Remove ``'pytest'`` and any other testing requirements from ``tests_require``, preferably removing the ``tests_requires`` option.
+- Select a tool to bootstrap and then run tests such as tox.
+
+Usage
+=====
+
+- Add 'pytest-runner' to your 'setup_requires'. Pin to '>=2.0,<3dev' (or
+  similar) to avoid pulling in incompatible versions.
+- Include 'pytest' and any other testing requirements to 'tests_require'.
+- Invoke tests with ``setup.py pytest``.
+- Pass ``--index-url`` to have test requirements downloaded from an alternate
+  index URL (unnecessary if specified for easy_install in setup.cfg).
+- Pass additional py.test command-line options using ``--addopts``.
+- Set permanent options for the ``python setup.py pytest`` command (like ``index-url``)
+  in the ``[pytest]`` section of ``setup.cfg``.
+- Set permanent options for the ``py.test`` run (like ``addopts`` or ``pep8ignore``) in the ``[pytest]``
+  section of ``pytest.ini`` or ``tox.ini`` or put them in the ``[tool:pytest]``
+  section of ``setup.cfg``. See `pytest issue 567
+  <https://github.com/pytest-dev/pytest/issues/567>`_.
+- Optionally, set ``test=pytest`` in the ``[aliases]`` section of ``setup.cfg``
+  to cause ``python setup.py test`` to invoke pytest.
+
+Example
+=======
+
+The most simple usage looks like this in setup.py::
+
+    setup(
+        setup_requires=[
+            'pytest-runner',
+        ],
+        tests_require=[
+            'pytest',
+        ],
+    )
+
+Additional dependencies require to run the tests (e.g. mock or pytest
+plugins) may be added to tests_require and will be downloaded and
+required by the session before invoking pytest.
+
+Follow `this search on github
+<https://github.com/search?utf8=%E2%9C%93&q=filename%3Asetup.py+pytest-runner&type=Code&ref=searchresults>`_
+for examples of real-world usage.
+
+Standalone Example
+==================
+
+This technique is deprecated - if you have standalone scripts
+you wish to invoke with dependencies, `use pip-run
+<https://pypi.org/project/pip-run>`_.
+
+Although ``pytest-runner`` is typically used to add pytest test
+runner support to maintained packages, ``pytest-runner`` may
+also be used to create standalone tests. Consider `this example
+failure <https://gist.github.com/jaraco/d979a558bc0bf2194c23>`_,
+reported in `jsonpickle #117
+<https://github.com/jsonpickle/jsonpickle/issues/117>`_
+or `this MongoDB test
+<https://gist.github.com/jaraco/0b9e482f5c0a1300dc9a>`_
+demonstrating a technique that works even when dependencies
+are required in the test.
+
+Either example file may be cloned or downloaded and simply run on
+any system with Python and Setuptools. It will download the
+specified dependencies and run the tests. Afterward, the the
+cloned directory can be removed and with it all trace of
+invoking the test. No other dependencies are needed and no
+system configuration is altered.
+
+Then, anyone trying to replicate the failure can do so easily
+and with all the power of pytest (rewritten assertions,
+rich comparisons, interactive debugging, extensibility through
+plugins, etc).
+
+As a result, the communication barrier for describing and
+replicating failures is made almost trivially low.
+
+Considerations
+==============
+
+Conditional Requirement
+-----------------------
+
+Because it uses Setuptools setup_requires, pytest-runner will install itself
+on every invocation of setup.py. In some cases, this causes delays for
+invocations of setup.py that will never invoke pytest-runner. To help avoid
+this contingency, consider requiring pytest-runner only when pytest
+is invoked::
+
+    needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv)
+    pytest_runner = ['pytest-runner'] if needs_pytest else []
+
+    # ...
+
+    setup(
+        #...
+        setup_requires=[
+            #... (other setup requirements)
+        ] + pytest_runner,
+    )
+
+For Enterprise
+==============
+
+Available as part of the Tidelift Subscription.
+
+This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.
+
+`Learn more <https://tidelift.com/subscription/pkg/pypi-PROJECT?utm_source=pypi-PROJECT&utm_medium=referral&utm_campaign=github>`_.
+
+Security Contact
+================
+
+To report a security vulnerability, please use the
+`Tidelift security contact <https://tidelift.com/security>`_.
+Tidelift will coordinate the fix and disclosure.
diff --git a/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/RECORD b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/RECORD
new file mode 100644
index 0000000..d7ff24d
--- /dev/null
+++ b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/RECORD
@@ -0,0 +1,7 @@
+ptr/__init__.py,sha256=0UfzhCooVgCNTBwVEOPOVGEPck4pnl_6PTfsC-QzNGM,6730
+pytest_runner-6.0.1.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050
+pytest_runner-6.0.1.dist-info/METADATA,sha256=Ho3FvAFjFHeY5OQ64WFzkLigFaIpuNr4G3uSmOk3nho,7319
+pytest_runner-6.0.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
+pytest_runner-6.0.1.dist-info/entry_points.txt,sha256=BqezBqeO63XyzSYmHYE58gKEFIjJUd-XdsRQkXHy2ig,58
+pytest_runner-6.0.1.dist-info/top_level.txt,sha256=DPzHbWlKG8yq8EOD5UgEvVNDWeJRPyimrwfShwV6Iuw,4
+pytest_runner-6.0.1.dist-info/RECORD,,
diff --git a/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/WHEEL b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/WHEEL
new file mode 100644
index 0000000..98c0d20
--- /dev/null
+++ b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/WHEEL
@@ -0,0 +1,5 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.42.0)
+Root-Is-Purelib: true
+Tag: py3-none-any
+
diff --git a/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/entry_points.txt b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/entry_points.txt
new file mode 100644
index 0000000..0860670
--- /dev/null
+++ b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/entry_points.txt
@@ -0,0 +1,3 @@
+[distutils.commands]
+ptr = ptr:PyTest
+pytest = ptr:PyTest
diff --git a/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/requires.txt b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/requires.txt
new file mode 100644
index 0000000..1535188
--- /dev/null
+++ b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/requires.txt
@@ -0,0 +1,17 @@
+
+[docs]
+sphinx
+jaraco.packaging>=9
+rst.linker>=1.9
+jaraco.tidelift>=1.4
+
+[testing]
+pytest>=6
+pytest-checkdocs>=2.4
+pytest-flake8
+pytest-cov
+pytest-enabler>=1.0.1
+pytest-virtualenv
+types-setuptools
+pytest-black>=0.3.7
+pytest-mypy>=0.9.1
diff --git a/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/top_level.txt b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/top_level.txt
new file mode 100644
index 0000000..e9148ae
--- /dev/null
+++ b/.eggs/pytest_runner-6.0.1-py3.12.egg/EGG-INFO/top_level.txt
@@ -0,0 +1 @@
+ptr
diff --git a/.eggs/pytest_runner-6.0.1-py3.12.egg/ptr/__init__.py b/.eggs/pytest_runner-6.0.1-py3.12.egg/ptr/__init__.py
new file mode 100644
index 0000000..41192fa
--- /dev/null
+++ b/.eggs/pytest_runner-6.0.1-py3.12.egg/ptr/__init__.py
@@ -0,0 +1,216 @@
+"""
+Implementation
+"""
+
+import os as _os
+import shlex as _shlex
+import contextlib as _contextlib
+import sys as _sys
+import operator as _operator
+import itertools as _itertools
+import warnings as _warnings
+
+import pkg_resources
+import setuptools.command.test as orig
+from setuptools import Distribution
+
+
+@_contextlib.contextmanager
+def _save_argv(repl=None):
+    saved = _sys.argv[:]
+    if repl is not None:
+        _sys.argv[:] = repl
+    try:
+        yield saved
+    finally:
+        _sys.argv[:] = saved
+
+
+class CustomizedDist(Distribution):
+
+    allow_hosts = None
+    index_url = None
+
+    def fetch_build_egg(self, req):
+        """Specialized version of Distribution.fetch_build_egg
+        that respects respects allow_hosts and index_url."""
+        from setuptools.command.easy_install import easy_install
+
+        dist = Distribution({'script_args': ['easy_install']})
+        dist.parse_config_files()
+        opts = dist.get_option_dict('easy_install')
+        keep = (
+            'find_links',
+            'site_dirs',
+            'index_url',
+            'optimize',
+            'site_dirs',
+            'allow_hosts',
+        )
+        for key in list(opts):
+            if key not in keep:
+                del opts[key]  # don't use any other settings
+        if self.dependency_links:
+            links = self.dependency_links[:]
+            if 'find_links' in opts:
+                links = opts['find_links'][1].split() + links
+            opts['find_links'] = ('setup', links)
+        if self.allow_hosts:
+            opts['allow_hosts'] = ('test', self.allow_hosts)
+        if self.index_url:
+            opts['index_url'] = ('test', self.index_url)
+        install_dir_func = getattr(self, 'get_egg_cache_dir', _os.getcwd)
+        install_dir = install_dir_func()
+        cmd = easy_install(
+            dist,
+            args=["x"],
+            install_dir=install_dir,
+            exclude_scripts=True,
+            always_copy=False,
+            build_directory=None,
+            editable=False,
+            upgrade=False,
+            multi_version=True,
+            no_report=True,
+            user=False,
+        )
+        cmd.ensure_finalized()
+        return cmd.easy_install(req)
+
+
+class PyTest(orig.test):
+    """
+    >>> import setuptools
+    >>> dist = setuptools.Distribution()
+    >>> cmd = PyTest(dist)
+    """
+
+    user_options = [
+        ('extras', None, "Install (all) setuptools extras when running tests"),
+        (
+            'index-url=',
+            None,
+            "Specify an index url from which to retrieve dependencies",
+        ),
+        (
+            'allow-hosts=',
+            None,
+            "Whitelist of comma-separated hosts to allow "
+            "when retrieving dependencies",
+        ),
+        (
+            'addopts=',
+            None,
+            "Additional options to be passed verbatim to the pytest runner",
+        ),
+    ]
+
+    def initialize_options(self):
+        self.extras = False
+        self.index_url = None
+        self.allow_hosts = None
+        self.addopts = []
+        self.ensure_setuptools_version()
+
+    @staticmethod
+    def ensure_setuptools_version():
+        """
+        Due to the fact that pytest-runner is often required (via
+        setup-requires directive) by toolchains that never invoke
+        it (i.e. they're only installing the package, not testing it),
+        instead of declaring the dependency in the package
+        metadata, assert the requirement at run time.
+        """
+        pkg_resources.require('setuptools>=27.3')
+
+    def finalize_options(self):
+        if self.addopts:
+            self.addopts = _shlex.split(self.addopts)
+
+    @staticmethod
+    def marker_passes(marker):
+        """
+        Given an environment marker, return True if the marker is valid
+        and matches this environment.
+        """
+        return (
+            not marker
+            or not pkg_resources.invalid_marker(marker)
+            and pkg_resources.evaluate_marker(marker)
+        )
+
+    def install_dists(self, dist):
+        """
+        Extend install_dists to include extras support
+        """
+        return _itertools.chain(
+            orig.test.install_dists(dist), self.install_extra_dists(dist)
+        )
+
+    def install_extra_dists(self, dist):
+        """
+        Install extras that are indicated by markers or
+        install all extras if '--extras' is indicated.
+        """
+        extras_require = dist.extras_require or {}
+
+        spec_extras = (
+            (spec.partition(':'), reqs) for spec, reqs in extras_require.items()
+        )
+        matching_extras = (
+            reqs
+            for (name, sep, marker), reqs in spec_extras
+            # include unnamed extras or all if self.extras indicated
+            if (not name or self.extras)
+            # never include extras that fail to pass marker eval
+            and self.marker_passes(marker)
+        )
+        results = list(map(dist.fetch_build_eggs, matching_extras))
+        return _itertools.chain.from_iterable(results)
+
+    @staticmethod
+    def _warn_old_setuptools():
+        msg = (
+            "pytest-runner will stop working on this version of setuptools; "
+            "please upgrade to setuptools 30.4 or later or pin to "
+            "pytest-runner < 5."
+        )
+        ver_str = pkg_resources.get_distribution('setuptools').version
+        ver = pkg_resources.parse_version(ver_str)
+        if ver < pkg_resources.parse_version('30.4'):
+            _warnings.warn(msg)
+
+    def run(self):
+        """
+        Override run to ensure requirements are available in this session (but
+        don't install them anywhere).
+        """
+        self._warn_old_setuptools()
+        dist = CustomizedDist()
+        for attr in 'allow_hosts index_url'.split():
+            setattr(dist, attr, getattr(self, attr))
+        for attr in (
+            'dependency_links install_requires tests_require extras_require '
+        ).split():
+            setattr(dist, attr, getattr(self.distribution, attr))
+        installed_dists = self.install_dists(dist)
+        if self.dry_run:
+            self.announce('skipping tests (dry run)')
+            return
+        paths = map(_operator.attrgetter('location'), installed_dists)
+        with self.paths_on_pythonpath(paths):
+            with self.project_on_sys_path():
+                return self.run_tests()
+
+    @property
+    def _argv(self):
+        return ['pytest'] + self.addopts
+
+    def run_tests(self):
+        """
+        Invoke pytest, replacing argv. Return result code.
+        """
+        with _save_argv(_sys.argv[:1] + self.addopts):
+            result_code = __import__('pytest').main()
+            if result_code:
+                raise SystemExit(result_code)
diff --git a/BscElectrolyteModels.egg-info/PKG-INFO b/BscElectrolyteModels.egg-info/PKG-INFO
new file mode 100644
index 0000000..4600c3c
--- /dev/null
+++ b/BscElectrolyteModels.egg-info/PKG-INFO
@@ -0,0 +1,117 @@
+Metadata-Version: 2.1
+Name: BscElectrolyteModels
+Version: 1.0
+Summary: A description is yet to follow
+Home-page: https://git.rwth-aachen.de/JanHab/Bsc-ElectrolyteModels
+Author: Jan Habscheid, Lambert Theisen, Manuel Torrilhon
+Author-email: Jan.Habscheid@rwth-aachen.de, lambert.theisen@rwth-aachen.de, mt@mathcces.rwth-aachen.de
+License: GNU General Public License v3.0 or later
+Keywords: fenics-project,Battery Simulation,finite element method
+Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
+Classifier: Programming Language :: Python :: 3
+Requires-Python: ==3.12.3
+Description-Content-Type: text/markdown
+License-File: LICENSE
+Requires-Dist: pyvista==0.43.10
+Requires-Dist: numpy==1.26.4
+Requires-Dist: scipy==1.14.0
+Provides-Extra: notebook
+Requires-Dist: jupyter>=1.0.0; extra == "notebook"
+Provides-Extra: tests
+Requires-Dist: pytest==8.3.3; extra == "tests"
+Provides-Extra: docs
+Requires-Dist: sphinx==7.3.7; extra == "docs"
+Requires-Dist: myst-parser==4.0.0; extra == "docs"
+Requires-Dist: sphinx-copybotton==0.5.2; extra == "docs"
+Requires-Dist: sphinx_rtd_theme==3.0.1; extra == "docs"
+Provides-Extra: build
+Requires-Dist: build>=0.7.0; extra == "build"
+Provides-Extra: dev
+Requires-Dist: BScElectrolytemodels[tests]; extra == "dev"
+Requires-Dist: BScElectrolytemodels[docs]; extra == "dev"
+Requires-Dist: BScElectrolytemodels[build]; extra == "dev"
+
+# Reproducibility Repository for Numerical Treatment of a Thermodynamically Consistent Electrolyte Model (B.Sc. Thesis - Jan Habscheid)
+
+[![Pipeline Status](https://git.rwth-aachen.de/Jan.Habscheid/bsc-electrolytemodels/badges/main/pipeline.svg)](https://git.rwth-aachen.de/Jan.Habscheid/bsc-electrolytemodels/pipelines)
+[![Documentation](https://img.shields.io/badge/docs-latest-blue)](https://janhab.pages.rwth-aachen.de/bsc-electrolytemodels/)
+[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.13645296.svg)](https://doi.org/10.5281/zenodo.13645296)
+[![GitLab Version](https://img.shields.io/badge/version-1.0-blue.svg)](https://git.rwth-aachen.de/jan.habscheid/bsc-electrolytemodels/-/tags)
+[![License](https://img.shields.io/badge/license-GPLv3-blue)](https://git.rwth-aachen.de/Jan.Habscheid/bsc-electrolytemodels/-/blob/main/LICENSE?ref_type=heads)
+
+## Thesis
+
+This repository contains the code to reproduce the results presented in the bachelor thesis: Numerical Treatment of a Thermodynamically Consistent Electrolyte Model
+Find the thesis at [https://doi.org/10.18154/RWTH-2024-09837](https://doi.org/10.18154/RWTH-2024-09837)
+
+### Abstract
+
+Batteries play a crucial role in the energy transition. The production of green energy depends on external factors. Storing energy in batteries is necessary to access green energy at any time.
+
+Better optimized batteries are essential for the future. Lifetime, loading time, and energy loss are just some aspects that must be improved to prepare for a greener future. Numerical simulations are crucial to understanding and optimizing batteries' behavior. Those simulations enable researchers to test many different materials without considerable additional expenses to, for example, find the best combination of anions and cations.
+
+The classical Nernst-Planck model for the ion transport in an electrolyte fails to predict the correct concentration in the boundaries of the electrolyte. This work will present and analyze a thermodynamically consistent electrolyte model with dimensionless units under isothermal conditions. A simplified version of the system for the one-dimensional equilibrium of an ideal mixture and the incompressible limit will be considered. The numerical implementation of the model with the open-source software FEniCSx will be discussed. Furthermore, the influence of different boundary conditions, material parameters, solvation, and compressibility on the electric potential, pressure, and ion concentration will be investigated, and the model will be compared with the classical Nernst-Planck model. Examples of the double layer capacity and electrolytic diode will be considered.
+
+## Installation
+
+As a numerical solver, mainly FEniCSx was used and installed via conda.
+All the calculations were performed on a Linux machine. According to the documentation, everything should work well on macOS, but this was not tested. FEniCSx offers some beta versions for Windows support, but it is recommended to use WSL2 instead.
+
+```
+conda create --name fenicsx-env python=3.12.3 -y
+conda activate fenicsx-env
+conda install -c conda-forge fenics-dolfinx=0.8.0 mpich=4.2.1 pyvista=0.43.10 matplotlib=3.8.4 numpy=1.26.4 scipy=1.14.0 pytest==8.3.3 -y
+```
+
+### Alternative installation
+
+Use the "environment.yml" file to install all necessary environments
+
+```
+conda env create -f environment.yml
+```
+
+### macOS installation using Docker
+
+```
+docker compose build
+docker compose run solver
+```
+
+### Testing
+
+Use pytest with 
+```
+python -m pytest
+```
+
+to verify that everything was installed correctly.
+
+
+## Usage
+
+Find the visualizations from the thesis and some extra calculations in the "examples" folder.
+In the subfolder "ReproducableCode" is the code, to execute the calculations with some first visualizations.
+The subfolder "Data" stores the data for all the simulations in a *.npz file, which can be read with numpy `np.load(file.npz)`.
+"Visualizations" creates the necessary figures from the thesis and stores them in *.svg format in "Figures".
+
+In "src" there are the generic FEniCSx implementations, that were used to calculate the examples.
+
+
+## Contact
+
+**Author**
+- Jan Habscheid
+- Jan.Habscheid@rwth-aachen.de
+
+**Supervisor**
+- Dr. Lambert Theissen
+- ACoM - Applied and Computational Mathematics
+- RWTH Aachen University
+- theisen@acom.rwth-aachen.de
+
+**Supervisor**
+- Prof. Dr. Manuel Torrilhon
+- ACoM - Applied and Computational Mathematics
+- RWTH Aachen University
+- mt@acom.rwth-aachen.de
diff --git a/BscElectrolyteModels.egg-info/SOURCES.txt b/BscElectrolyteModels.egg-info/SOURCES.txt
new file mode 100644
index 0000000..ec989ab
--- /dev/null
+++ b/BscElectrolyteModels.egg-info/SOURCES.txt
@@ -0,0 +1,23 @@
+LICENSE
+README.md
+pyproject.toml
+setup.cfg
+setup.py
+BscElectrolyteModels.egg-info/PKG-INFO
+BscElectrolyteModels.egg-info/SOURCES.txt
+BscElectrolyteModels.egg-info/dependency_links.txt
+BscElectrolyteModels.egg-info/entry_points.txt
+BscElectrolyteModels.egg-info/requires.txt
+BscElectrolyteModels.egg-info/top_level.txt
+BscElectrolyteModels.egg-info/zip-safe
+src/ElectrolyticDiode.py
+src/Eq02.py
+src/Eq04.py
+src/EqN.py
+src/Helper_DoubleLayerCapacity.py
+src/__init__.py
+tests/test_ElectrolyticDiode.py
+tests/test_Eq02.py
+tests/test_Eq04.py
+tests/test_EqN.py
+tests/test_Helper_DoubleLayerCapacity.py
\ No newline at end of file
diff --git a/BscElectrolyteModels.egg-info/dependency_links.txt b/BscElectrolyteModels.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/BscElectrolyteModels.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/BscElectrolyteModels.egg-info/entry_points.txt b/BscElectrolyteModels.egg-info/entry_points.txt
new file mode 100644
index 0000000..7bcc5d3
--- /dev/null
+++ b/BscElectrolyteModels.egg-info/entry_points.txt
@@ -0,0 +1,2 @@
+[console_scripts]
+my-example-utility = example.example_module:main
diff --git a/BscElectrolyteModels.egg-info/requires.txt b/BscElectrolyteModels.egg-info/requires.txt
new file mode 100644
index 0000000..f08ddad
--- /dev/null
+++ b/BscElectrolyteModels.egg-info/requires.txt
@@ -0,0 +1,23 @@
+pyvista==0.43.10
+numpy==1.26.4
+scipy==1.14.0
+
+[build]
+build>=0.7.0
+
+[dev]
+BScElectrolytemodels[tests]
+BScElectrolytemodels[docs]
+BScElectrolytemodels[build]
+
+[docs]
+sphinx==7.3.7
+myst-parser==4.0.0
+sphinx-copybotton==0.5.2
+sphinx_rtd_theme==3.0.1
+
+[notebook]
+jupyter>=1.0.0
+
+[tests]
+pytest==8.3.3
diff --git a/BscElectrolyteModels.egg-info/top_level.txt b/BscElectrolyteModels.egg-info/top_level.txt
new file mode 100644
index 0000000..eac2d36
--- /dev/null
+++ b/BscElectrolyteModels.egg-info/top_level.txt
@@ -0,0 +1 @@
+Bsc-ElectrolyteModels
diff --git a/BscElectrolyteModels.egg-info/zip-safe b/BscElectrolyteModels.egg-info/zip-safe
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/BscElectrolyteModels.egg-info/zip-safe
@@ -0,0 +1 @@
+
diff --git a/README.md b/README.md
index 0067dac..5c040e9 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ All the calculations were performed on a Linux machine. According to the documen
 ```
 conda create --name fenicsx-env python=3.12.3 -y
 conda activate fenicsx-env
-conda install -c conda-forge fenics-dolfinx=0.8.0 mpich=4.2.1 pyvista=0.43.10 matplotlib=3.8.4 numpy=1.26.4 scipy=1.14.0 pytest==8.3.3 -y
+conda install -c conda-forge fenics-dolfinx=0.8.0 mpich=4.2.1 pyvista=0.43.10 gcc=12.4.0 matplotlib=3.8.4 numpy=1.26.4 scipy=1.14.0 pytest==8.3.3 -y
 ```
 
 ### Alternative installation
diff --git a/build/lib/Bsc-ElectrolyteModels/ElectrolyticDiode.py b/build/lib/Bsc-ElectrolyteModels/ElectrolyticDiode.py
new file mode 100644
index 0000000..836b48c
--- /dev/null
+++ b/build/lib/Bsc-ElectrolyteModels/ElectrolyticDiode.py
@@ -0,0 +1,401 @@
+'''
+Jan Habscheid
+Jan.Habscheid@rwth-aachen.de
+
+This module solves the dimensionless system of equations for the example of an electric diode
+
+# ! Disclaimer: The results conform with [A Numerical Strategy for Nernst–Planck Systems with Solvation Effect, J. Fuhrmann, DOI:10.1002/fuce.201500215]. As the size of the domain, the boundary conditions, and the parameters are chosen differently, it can not be expected to match the same results quantitatively but qualitatively. In [Fuhrmann], only the potential and the cations are visualized. The potential behaves the same, and the cations are pushed to the outside of the domain for the forward bias and to the center of the domain for the backward bias. Furthermore, a rectification effect in the concentrations of the ions cannot be seen, as the range of the concentrations is the same along the different biases. On the other hand, this rectification process can be observed in [Entropy and convergence analysis for two finite volume schemes for a Nernst-Planck-Poisson system with ion volume constraints, B. Gaudeaul, J. Fuhrmann, DOI:10.1007/s00211-022-01279-y]. The electric potential can be verified to match the behavior from [Gaudeaul & Fuhrmann]. Furthermore, the ion concentrations can also be validated qualitatively. However, in [Gaudeaul & Fuhrmann], a rectification effect can be observed, reducing the concentrations of anions and cations for the reverse bias and no bias compared to the forward bias.
+'''
+
+import numpy as np
+from mpi4py import MPI
+from dolfinx import mesh, fem, log, io
+from dolfinx.fem.petsc import NonlinearProblem
+from dolfinx.nls.petsc import NewtonSolver
+from ufl import TestFunctions, split, dot, grad, dx, inner, ln
+from basix.ufl import element, mixed_element
+import matplotlib.pyplot as plt
+from ufl import Measure
+from dolfinx.mesh import locate_entities, meshtags
+
+def ElectrolyticDiode(Bias_type:str, phi_bias:float, g_phi:float, z_A:float, z_C:float, y_A_bath:float, y_C_bath:float, K:float|str, Lambda2:float, a2:float, number_cells:list, solvation:float = 0, PoissonBoltzmann:bool=False, relax_param:float=None, Lx:float=2, Ly:float=10, rtol:float=1e-8, max_iter:float=500, return_type:str='Vector'):
+    '''
+    Solves the system of equations for the example of an electric diode
+
+    Solve the dimensionless system of equations presented in: Numerical Treatment of a Thermodynamically Consistent Electrolyte Model, B.Sc. Thesis Habscheid 2024
+
+    ! If the Newton solver diverges, you may try to reduce the relaxation parameter.
+
+    Parameters
+    ----------
+    Bias_type : str
+        ForwardBias, NoBias, BackwardBias
+    phi_bias : float
+        Bias in φ
+    g_phi : float
+        Neumann boundary condition for φ
+    z_A : float
+        Charge number of species A
+    z_C : float
+        Charge number of species C
+    y_A_bath : float
+        Bath concentration of anions
+    y_C_bath : float
+        Bath concentration of cations
+    K : float | str
+        Dimensioness bulk modulus of the electrolyte. If 'incompressible', the system is solved for an incompressible electrolyte
+        ! Only implemented for incompressible mixtures, yet
+    Lambda2 : float
+        Dimensionless parameter
+    a2 : float
+        Dimensionless parameter
+    number_cells : int
+        Number of cells in the mesh
+    solvation : float, optional
+        solvation number, by default 0
+    PoissonBoltzmann : bool, optional
+        Solve classical Nernst-Planck model with the use of the Poisson-Boltzmann formulation if True, else solve the presented model by Dreyer, Guhlke, Müller, by default False
+    relax_param : float, optional
+        Relaxation parameter for the Newton solver
+        xₙ₊₁ = γ xₙ f(xₙ)/f'(xₙ) with γ the relaxation parameter
+        , by default None -> Determined automatically
+    Lx : float, optional
+        Length of domain in x-direction, by default 2
+    Ly : float, optional
+        Length of domain in y-direction, by default 10
+    rtol : float, optional
+        Relative tolerance for Newton solver, by default 1e-8
+    max_iter : float, optional
+        Maximum number of Newton iterations, by default 500
+    return_type : str, optional
+        Type of return value, by default 'Vector'
+        'Vector' -> Returns the solution as a numpy array for triangle elements
+        'Extended' -> Returns the solution as both, a numpy array for triangle elements and the fenicsx function u
+
+
+    Returns
+    -------
+    y_A_vector, y_C_vector, phi_vector, p_vector, x_vector
+        Returns atomic fractions for species A and C, electric potential, pressure, and the mesh as numpy arrays for triangle elements. x_vector is a list of both dimensions [x, y]
+        If return_type is 'Extended', also returns the fenicsx function u
+    '''
+    if K != 'incompressible':
+        raise NotImplementedError('Only incompressible electrolytes are implemented yet')
+    x0 = np.array([0, 0])
+    x1 = np.array([Lx, Ly])
+    match Bias_type:
+        case 'ForwardBias': phi_bias = phi_bias
+        case 'NoBias': phi_bias = 0
+        case 'BackwardBias': phi_bias = -phi_bias
+        case _: raise ValueError('Invalid Bias_type')
+
+    # Define boundaries
+    geom_tol = 1E-4 # ! Geometric tolerance, may need to be adjusted
+    def Left(x):
+        return np.isclose(x[0], x0[0], geom_tol, geom_tol)
+
+    def Right(x):
+        return np.isclose(x[0], x1[0], geom_tol, geom_tol)
+
+    def Top(x):
+        return np.isclose(x[1], x1[1], geom_tol, geom_tol)
+
+    def Bottom(x):
+        return np.isclose(x[1], x0[1], geom_tol, geom_tol)
+
+    def Right_Top(x):
+        NeumannPart = np.logical_and(1/2*Ly < x[1], x[1] < 3/4*Ly)
+        RightPart = np.isclose(x[0], x1[0], geom_tol, geom_tol)
+        return np.logical_and(RightPart, NeumannPart)
+
+    def Right_Bottom(x):
+        NeumannPart = np.logical_and(1/4*Ly < x[1], x[1] < 1/2*Ly)
+        RightPart = np.isclose(x[0], x1[0], geom_tol, geom_tol)
+        return np.logical_and(RightPart, NeumannPart)
+
+    def Left_Top(x):
+        NeumannPart = np.logical_and(1/2*Ly < x[1], x[1] < 3/4*Ly)
+        LeftPart = np.isclose(x[0], x0[0], geom_tol, geom_tol)
+        return np.logical_and(LeftPart, NeumannPart)
+
+    def Left_Bottom(x):
+        NeumannPart = np.logical_and(1/4*Ly < x[1], x[1] < 1/2*Ly)
+        LeftPart = np.isclose(x[0], x0[0], geom_tol, geom_tol)
+        return np.logical_and(LeftPart, NeumannPart)
+    
+    # Create the mesh
+    msh = mesh.create_rectangle(MPI.COMM_WORLD, [x0, x1], number_cells)
+
+    # Define Finite Elements
+    CG1_elem = element('Lagrange', msh.basix_cell(), 1)
+    # from ufl import FiniteElement
+    # CG1_elem = FiniteElement("Lagrange", msh.ufl_cell(), 1)
+
+    # Define Mixed Function Space
+    W_elem = mixed_element([CG1_elem, CG1_elem, CG1_elem, CG1_elem])
+    W = fem.functionspace(msh, W_elem)
+
+    # Define Trial- and Testfunctions
+    u = fem.Function(W)
+    y_A, y_C, phi, p = split(u)
+    (v_A, v_C, v_1, v_2) = TestFunctions(W)
+
+    # Define boundary conditions
+    W0, _ = W.sub(0).collapse()
+    W1, _ = W.sub(1).collapse()
+    W2, _ = W.sub(2).collapse()
+    W3, _ = W.sub(3).collapse()
+
+    def phi_bottom_(x):
+        return np.full_like(x[1], 0)
+    def phi_top_(x):
+        return np.full_like(x[1], phi_bias)
+    def y_A_bottom_(x):
+        return np.full_like(x[1], y_A_bath)
+    def y_A_top_(x):
+        return np.full_like(x[1], y_A_bath)
+    def y_C_bottom_(x):
+        return np.full_like(x[1], y_C_bath)
+    def y_C_top_(x):
+        return np.full_like(x[1], y_C_bath)
+    
+    phi_bottom_bcs = fem.Function(W2)
+    phi_bottom_bcs.interpolate(phi_bottom_)
+    phi_top_bcs = fem.Function(W2)
+    phi_top_bcs.interpolate(phi_top_)
+    y_A_bottom_bcs = fem.Function(W0)
+    y_A_bottom_bcs.interpolate(y_A_bottom_)
+    y_A_top_bcs = fem.Function(W0)
+    y_A_top_bcs.interpolate(y_A_top_)
+    y_C_bottom_bcs = fem.Function(W1)
+    y_C_bottom_bcs.interpolate(y_C_bottom_)
+    y_C_top_bcs = fem.Function(W1)
+    y_C_top_bcs.interpolate(y_C_top_)
+
+    # Identify face tags and create dirichlet conditions
+    facet_bottom_dofs = fem.locate_dofs_geometrical((W.sub(2), W.sub(2).collapse()[0]), Bottom)
+    facet_top_dofs = fem.locate_dofs_geometrical((W.sub(2), W.sub(2).collapse()[0]), Top)
+    bc_bottom_phi = fem.dirichletbc(phi_bottom_bcs, facet_bottom_dofs, W.sub(2))
+    bc_top_phi = fem.dirichletbc(phi_top_bcs, facet_top_dofs, W.sub(2))
+
+    facet_bottom_dofs = fem.locate_dofs_geometrical((W.sub(0), W.sub(0).collapse()[0]), Bottom)
+    bc_bottom_y_A = fem.dirichletbc(y_A_bottom_bcs, facet_bottom_dofs, W.sub(0))
+    facet_top_dofs = fem.locate_dofs_geometrical((W.sub(0), W.sub(0).collapse()[0]), Top)
+    bc_top_y_A = fem.dirichletbc(y_A_top_bcs, facet_top_dofs, W.sub(0))
+
+    facet_bottom_dofs = fem.locate_dofs_geometrical((W.sub(1), W.sub(1).collapse()[0]), Bottom)
+    bc_bottom_y_C = fem.dirichletbc(y_C_bottom_bcs, facet_bottom_dofs, W.sub(1))
+    facet_top_dofs = fem.locate_dofs_geometrical((W.sub(1), W.sub(1).collapse()[0]), Top)
+    bc_top_y_C = fem.dirichletbc(y_C_top_bcs, facet_top_dofs, W.sub(1))
+
+    # Collect boundary conditions
+    bcs = [bc_bottom_phi, bc_top_phi, bc_bottom_y_A, bc_top_y_A, bc_bottom_y_C, bc_top_y_C]
+    # bcs = [bc_bottom_phi, bc_top_phi, bc_bottom_y_A, bc_bottom_y_C]
+
+
+    # def p_bottom_(x):
+    #     return np.full_like(x[1], 0)
+    # def p_top_(x):
+    #     return np.full_like(x[1], 0)
+    # p_bottom_bcs = fem.Function(W3)
+    # p_bottom_bcs.interpolate(p_bottom_)
+    # p_top_bcs = fem.Function(W3)
+    # p_top_bcs.interpolate(p_top_)
+    # facet_bottom_dofs = fem.locate_dofs_geometrical((W.sub(3), W.sub(3).collapse()[0]), Bottom)
+    # facet_top_dofs = fem.locate_dofs_geometrical((W.sub(3), W.sub(3).collapse()[0]), Top)
+    # bc_bottom_p = fem.dirichletbc(p_bottom_bcs, facet_bottom_dofs, W.sub(3))
+    # bc_top_p = fem.dirichletbc(p_top_bcs, facet_top_dofs, W.sub(3))
+    # bcs.append(bc_bottom_p)
+    # bcs.append(bc_top_p)
+
+    # Variational formulation
+    if K == 'incompressible':
+        # def nF(y_A, y_C):
+        #     return (z_C * y_C + z_A * y_A) # n = 1
+    
+        # A = (
+        #     inner(grad(phi), grad(v_1)) * dx
+        #     - 1 / Lambda2 * nF(y_A, y_C) * v_1 * dx
+        # ) + (
+        #     inner(grad(p), grad(v_2)) * dx
+        #     + 1 / a2 * nF(y_A, y_C) * dot(grad(phi), grad(v_2)) * dx
+        # ) + (
+        #     inner(grad(ln(y_A) + a2 * solvation * p - ln(1-y_A-y_C) + z_A * phi), grad(v_A)) * dx
+        #     + inner(grad(ln(y_C) + a2 * solvation * p- ln(1-y_A-y_C) + z_C * phi), grad(v_C)) * dx
+        # )
+        # def nF(y_A, y_C):
+        #     # n = const = 1
+        #     return (z_C * y_C + z_A * y_A)
+
+        # def J_A(y_A, y_C, phi, p):
+        #     g_A = (solvation + 1) * a2 * (p - 1) # g_Aref, but constant and take gradient
+        #     mu_A = g_A + ln(y_A)
+        #     g_N = a2 * (p - 1) # solvation_N = 0, g_Sref, but constant and take gradient
+        #     mu_N = g_N + ln(1 - y_A - y_C)
+        #     return grad(mu_A - mu_N + z_A * phi)
+        #     # return grad(ln(y_A) - ln(1 - y_A - y_C) + z_A * phi)
+        
+        # def J_C(y_A, y_C, phi, p):
+        #     g_C = (solvation + 1) * a2 * (p - 1) # g_Cref, but constant and take gradient
+        #     mu_C = g_C + ln(y_C)
+        #     g_N = a2 * (p - 1)
+        #     mu_N = g_N + ln(1 - y_A - y_C)
+        #     return grad(mu_C - mu_N + z_C * phi)
+        #     # return grad(ln(y_C) - ln(1 - y_A - y_C) + z_C * phi)
+
+        def nF(y_A, y_C):
+            return (z_C * y_C + z_A * y_A)
+        
+        # Diffusion fluxes for species A and C
+        def J_A(y_A, y_C, phi, p):
+            return grad(ln(y_A) + a2 * (p - 1) * (solvation + 1) + z_A * phi)
+        
+        def J_C(y_A, y_C, phi, p):
+            return grad(ln(y_C) + a2 * (p - 1) * (solvation + 1) + z_C * phi)
+
+        # if PoissonBoltzmann:
+        #     def J_A(y_A, y_C, phi, p):
+        #         return grad(ln(y_A) + z_A * phi)
+        #     def J_C(y_A, y_C, phi, p):
+        #         return grad(ln(y_C) + z_C * phi)
+
+        A = (
+            inner(grad(phi), grad(v_1)) * dx
+            - 1 / Lambda2 * nF(y_A, y_C) * v_1 * dx
+        ) + (
+            inner(grad(p), grad(v_2)) * dx
+            + 1 / a2 * nF(y_A, y_C) * dot(grad(phi), grad(v_2)) * dx
+        ) + (
+            inner(J_A(y_A, y_C, phi, p), grad(v_A)) * dx
+            + inner(J_C(y_A, y_C, phi, p), grad(v_C)) * dx
+        )
+
+    # Define Neumann boundaries
+    boundaries = [(0, Right_Top), (1, Right_Bottom), (2, Left_Top), (3, Left_Bottom)]
+    facet_indices, facet_markers = [], []
+    fdim = msh.topology.dim - 1
+    for (marker, locator) in boundaries:
+        facets = locate_entities(msh, fdim, locator)
+        facet_indices.append(facets)
+        facet_markers.append(np.full_like(facets, marker))
+    facet_indices = np.hstack(facet_indices).astype(np.int32)
+    facet_markers = np.hstack(facet_markers).astype(np.int32)
+    sorted_facets = np.argsort(facet_indices)
+    facet_tag = meshtags(msh, fdim, facet_indices[sorted_facets], facet_markers[sorted_facets])
+    ds = Measure("ds", domain=msh, subdomain_data=facet_tag)
+    L = 0
+    L += (
+        inner(g_phi, v_1) * ds(0)
+        + inner(-g_phi, v_1) * ds(1)
+        # Uncomment, if you want to apply the Neumann bcs on both sides/ left side
+        # + inner(g_phi, v_1) * ds(2)
+        # + inner(-g_phi, v_1) * ds(3)
+    )
+
+    F = A + L
+
+    # Initialize initial guess for u
+    y_C_init = fem.Function(W1)
+    y_A_init = fem.Function(W0)
+    y_C_init.interpolate(lambda x: np.full_like(x[0], y_C_bath))
+    y_A_init.interpolate(lambda x: np.full_like(x[0], y_A_bath))
+
+    with u.vector.localForm() as u_loc:
+        u_loc.set(0)
+    u.sub(0).interpolate(y_A_init)
+    u.sub(1).interpolate(y_C_init)
+
+    # Define Nonlinear Problem
+    problem = NonlinearProblem(F, u, bcs=bcs)
+
+    solver = NewtonSolver(MPI.COMM_WORLD, problem)
+    solver.convergence_criterion = 'residual' #"incremental"
+    solver.rtol = rtol
+    solver.relaxation_parameter = relax_param
+    solver.max_it = max_iter
+    solver.report = True
+
+    # Solve the problem
+    log.set_log_level(log.LogLevel.INFO)
+    n, converged = solver.solve(u)
+    assert (converged)
+    print(f"Number of interations: {n:d}")
+
+    # Extract solution
+    y_A_vector = u.sub(0).collapse().x.array
+    y_C_vector = u.sub(1).collapse().x.array
+    phi_vector = u.sub(2).collapse().x.array
+    p_vector = u.sub(3).collapse().x.array
+
+    X = W.sub(0).collapse()[0].tabulate_dof_coordinates()
+    x_vector = [X[:, 0], X[:, 1]]
+
+    if return_type == 'Vector':
+        return y_A_vector, y_C_vector, phi_vector, p_vector, x_vector
+    elif return_type == 'Extended':
+        return y_A_vector, y_C_vector, phi_vector, p_vector, x_vector, u
+    else:
+        raise ValueError('Invalid return_type')
+
+if __name__ == '__main__':
+    phi_bias = 10#10
+    Bias_type = 'ForwardBias' # 'ForwardBias', 'NoBias', 'BackwardBias'
+    g_phi = 350#5
+    y_fixed = 0.01#0.01
+    z_A = -1.0
+    z_C = 1.0
+    K = 'incompressible'
+    Lambda2 = 8.553e-6 # ! Change back to 1e-6
+    # g_phi *= np.sqrt(Lambda2) # ! Unsure about this scaling
+    # g_phi *= Lambda2
+    # g_phi = g_phi / np.sqrt(Lambda2)
+    a2 = 7.5412e-4
+    number_cells = [20, 128]#[20, 100]
+    Lx = 0.02
+    Ly = 0.1
+    x0 = np.array([0, 0])
+    x1 = np.array([Lx, Ly])
+    refinement_style = 'uniform'
+    solvation = 5
+    PoissonBoltzmann = False
+    rtol = 1e-3 # ToDo: Change back to 1e-8, currently just for testing
+    relax_param = 0.15 # 0.1
+    max_iter = 15_000
+
+    # Solve the system
+    y_A, y_C, phi, p, X = ElectrolyticDiode(Bias_type, phi_bias, g_phi, z_A, z_C, y_fixed, y_fixed, K, Lambda2, a2, number_cells, solvation, PoissonBoltzmann, relax_param, Lx, Ly, rtol, max_iter, return_type='Vector')
+    x, y = X[0], X[1]
+    y_S = 1 - y_A - y_C
+
+    # Plot results
+    levelsf = 10
+    levels = 10    
+    fig, axs = plt.subplots(nrows=2, ncols=3, figsize=(8,10))
+
+    c = axs[0,0].tricontourf(x, y, y_A, levelsf)
+    fig.colorbar(c)
+    axs[0,0].tricontour(x, y, y_A, levels, colors='black')
+    axs[0,0].set_title('$y_A$')
+
+    c = axs[0,1].tricontourf(x, y, y_C, levelsf)
+    fig.colorbar(c)
+    axs[0,1].tricontour(x, y, y_C, levels, colors='black')
+    axs[0,1].set_title('$y_C$')
+
+    c = axs[0,2].tricontourf(x, y, y_S, levelsf)
+    fig.colorbar(c)
+    axs[0,2].tricontour(x, y, y_S, levels, colors='black')
+    axs[0,2].set_title('$y_S$')
+
+    c = axs[1,0].tricontourf(x, y, phi, levelsf)
+    fig.colorbar(c)
+    axs[1,0].tricontour(x, y, phi, levels, colors='black')
+    axs[1,0].set_title('$\\varphi$')
+
+    c = axs[1,1].tricontourf(x, y, p, levelsf)
+    fig.colorbar(c)
+    axs[1,1].tricontour(x, y, p, levels, colors='black')
+    axs[1,1].set_title('$p$')
+
+    fig.tight_layout()
+    fig.show() 
\ No newline at end of file
diff --git a/build/lib/Bsc-ElectrolyteModels/Eq02.py b/build/lib/Bsc-ElectrolyteModels/Eq02.py
new file mode 100644
index 0000000..0ec56e7
--- /dev/null
+++ b/build/lib/Bsc-ElectrolyteModels/Eq02.py
@@ -0,0 +1,309 @@
+'''
+Jan Habscheid
+Jan.Habscheid@rwth-aachen.de
+
+This file implements the fenics solver for the reduced systme of equations to two equations for the electric potential and the pressure.
+'''
+
+import numpy as np
+from mpi4py import MPI
+from dolfinx import mesh, fem, log
+from dolfinx.fem.petsc import NonlinearProblem
+from dolfinx.nls.petsc import NewtonSolver
+from ufl import TestFunctions, split, dot, grad, dx, inner, Mesh, exp
+from basix.ufl import element, mixed_element
+import matplotlib.pyplot as plt
+
+# Define mesh
+def create_refined_mesh(refinement_style:str, number_cells:int) -> Mesh:
+    '''
+    Creates a one-dimensional mesh with a refined region at the left boundary
+
+    Parameters
+    ----------
+    refinement_style : str
+        How the mesh should be refined. Options are 'log', 'hard_log', 'hard_hard_log'
+    number_cells : int
+        Number of cells in the mesh
+
+    Returns
+    -------
+    Mesh
+        One-dimensional mesh, ready for use in FEniCSx
+    '''
+    if refinement_style == 'log':
+        coordinates_np = (np.logspace(0, 1, number_cells+1) - 1) / 9
+    elif refinement_style == 'hard_log':
+        coordinates_np1 = (np.logspace(0,1,int(number_cells*0.9)+1,endpoint=False)-1)/9 * 0.1
+        coordinates_np2 = 0.1 + (np.logspace(0,1,int(number_cells*0.1)+1)-1)/9 * 0.9
+        coordinates_np = np.concatenate((coordinates_np1, coordinates_np2), axis=0)
+    elif refinement_style == 'hard_hard_log':
+        coordinates_np1 = (np.logspace(0,1,int(number_cells*0.9)+1,endpoint=False)-1)/9 * 0.004
+        coordinates_np2 = 0.004 + (np.logspace(0,1,int(number_cells*0.1)+1)-1)/9 * 0.996
+        coordinates_np = np.concatenate((coordinates_np1, coordinates_np2), axis=0)
+    num_vertices = len(coordinates_np)
+    num_cells = num_vertices - 1
+    cells_np = np.column_stack((np.arange(num_cells), np.arange(1, num_cells+1)))
+    gdim = 1
+    shape = 'interval' # 'interval', 'triangle', 'quadrilateral', 'tetrahedron', 'hexahedron'
+    degree = 1
+    domain = Mesh(element("Lagrange", shape, 1, shape=(1,)))
+    coordinates_np_ = []
+    [coordinates_np_.append([coord]) for coord in coordinates_np]
+    msh = mesh.create_mesh(MPI.COMM_WORLD, cells_np, coordinates_np_, domain)
+    return msh
+
+def solve_System_2eq(phi_left:float, phi_right:float, p_right:float, z_A:float, z_C:float, y_A_R:float, y_C_R:float, K:float|str, Lambda2:float, a2:float, number_cells:int, solvation:float = 0, relax_param:float=None, x0:float=0, x1:float=1, refinement_style:str='uniform', return_type:str='Scalar', rtol:float=1e-8, max_iter:float=500):
+    '''
+    Solve the simplified dimensionless system of equations presented in: Numerical Treatment of a Thermodynamically Consistent Electrolyte Model, B.Sc. Thesis Habscheid 2024
+
+    System of equations:
+        λ²Δ φ =−L²n^F
+        
+        a²∇p=−n^F∇ φ
+        
+    with the space charge
+        n^F = z_A y_A(φ, p) + z_C y_C(φ ,p)
+
+    if the mixture is compressible: 
+        y_alpha = C_alpha * (K+p−1)^(−κ+1)a²K exp(−z_α φ)
+
+    if the mixture is incompressible: 
+        y_alpha = D_alpha * exp(−(κ+1)a²p−z_α φ)
+
+    with φ the electric potential, p the pressure, n^F the total free charge density, J_α the diffusion fluxes of species α, λ² a dimensionless parameter, L²=1, a² a dimensionless parameter, N the number of species, and α the species index.
+
+    ! If the Newton solver diverges, you may try to reduce the relaxation parameter.
+
+    Parameters
+    ----------
+    phi_left : float
+        Value of φ at the left boundary
+    phi_right : float
+        Value of φ at the right boundary
+    p_right : float
+        Value of p at the right boundary
+    z_A : float
+        Charge number of species A
+    z_C : float
+        Charge number of species C
+    y_A_R : float
+        Atomic fractions of species A at right boundary
+    y_C_R : float
+        Atomic fractions of species C at right boundary
+    K : float | str
+        Dimensioness bulk modulus of the electrolyte. If 'incompressible', the system is solved for an incompressible electrolyte
+    Lambda2 : float
+        Dimensionless parameter
+    a2 : float
+        Dimensionless parameter
+    number_cells : int
+        Number of cells in the mesh
+    solvation : float, optional
+        solvation number, by default 0
+    relax_param : float, optional
+        Relaxation parameter for the Newton solver
+        xₙ₊₁ = γ xₙ f(xₙ)/f'(xₙ) with γ the relaxation parameter
+        , by default None -> Determined automatically
+    x0 : float, optional
+        Left boundary of the domain, by default 0
+    x1 : float, optional
+        Right boundary of the domain, by default 1
+    refinement_style : str, optional
+        Specify for refinement towards zero
+        Options are 'uniform', 'log', 'hard_log', 'hard_hard_log' by default 'uniform'
+    return_type : str, optional
+        'Vector' or 'Scalar', 'Scalar' returns dolfinx.fem type and 'Vector' numpy arrays of the solution, by default 'Scalar'
+    rtol : float, optional
+        Relative tolerance for Newton solver, by default 1e-8
+    max_iter : float, optional
+        Maximum number of Newton iterations, by default 500
+
+    Returns
+    -------
+    y_A, y_C, phi, p, msh
+        Returns atomic fractions for species A and C, electric potential, pressure, and the mesh
+        If return_type is 'Vector', the solution is returned as numpy arrays
+    '''
+    if return_type == 'Scalar':
+        raise NotImplementedError('Scalar return type is not implemented yet')
+    # Define boundaries of the domain
+    x0 = 0
+    x1 = 1
+
+    # Define boundaries for the boundary conditions
+    def Left(x):
+        return np.isclose(x[0], x0)
+
+    def Right(x):
+        return np.isclose(x[0], x1)
+    
+    # Create mesh
+    if refinement_style == 'uniform':
+        msh = mesh.create_unit_interval(MPI.COMM_WORLD, number_cells, dtype=np.float64)
+    else:
+        msh = create_refined_mesh(refinement_style, number_cells)
+
+    # Define Finite Elements
+    CG1_elem = element('Lagrange', msh.basix_cell(), 1)
+
+    # Define Mixed Function Space
+    W_elem = mixed_element([CG1_elem, CG1_elem])#, CG1_elem, CG1_elem])
+    W = fem.functionspace(msh, W_elem)
+
+    # Define Trial- and Testfunctions
+    u = fem.Function(W)
+    phi, p = split(u)
+    (v_1, v_2) = TestFunctions(W)
+
+    # Collapse function space for bcs
+    W0, _ = W.sub(0).collapse()
+    W1, _ = W.sub(1).collapse()
+    
+    # Define boundary conditions values
+    def phi_left_(x):
+        return np.full_like(x[0], phi_left)
+    def phi_right_(x):
+        return np.full_like(x[0], phi_right)
+    def p_right_(x):
+        return np.full_like(x[0], p_right)
+    
+    # Interpolate bcs functions
+    phi_left_bcs = fem.Function(W0)
+    phi_left_bcs.interpolate(phi_left_)
+    phi_right_bcs = fem.Function(W0)
+    phi_right_bcs.interpolate(phi_right_)
+    p_right_bcs = fem.Function(W1)
+    p_right_bcs.interpolate(p_right_)
+    
+    # Identify dofs for boundary conditions
+    # Define boundary conditions
+    facet_left_dofs = fem.locate_dofs_geometrical((W.sub(0), W.sub(0).collapse()[0]), Left)
+    facet_right_dofs = fem.locate_dofs_geometrical((W.sub(0), W.sub(0).collapse()[0]), Right)
+    bc_left_phi = fem.dirichletbc(phi_left_bcs, facet_left_dofs, W.sub(0))
+    bc_right_phi = fem.dirichletbc(phi_right_bcs, facet_right_dofs, W.sub(0))
+
+    facet_right_dofs = fem.locate_dofs_geometrical((W.sub(1), W.sub(1).collapse()[0]), Right)
+    bc_right_p = fem.dirichletbc(p_right_bcs, facet_right_dofs, W.sub(1))
+
+    
+    # Combine boundary conditions into list
+    bcs = [bc_left_phi, bc_right_phi, bc_right_p]
+
+    def y_A(phi, p):
+        D_A = y_A_R / exp(-(solvation + 1) * a2 * p_right - z_A * phi_right)
+        return D_A * exp(-(solvation + 1) * a2 * p - z_A * phi)
+    
+    def y_C(phi, p):
+        D_C = y_C_R / exp(-(solvation + 1) * a2 * p_right - z_C * phi_right)
+        return D_C * exp(-(solvation + 1) * a2 * p - z_C * phi)
+    
+
+    # Define variational problem
+    if K == 'incompressible':
+        # total free charge density
+        def nF(y_A, y_C, p):
+            return (z_C * y_C + z_A * y_A)
+    else: 
+        # total number density
+        def n(p):
+            return (p-1)/K + 1
+        
+        # total free charge density
+        def nF(y_A, y_C, p):
+            return (z_C * y_C + z_A * y_A) * n(p)
+    # Variational Form
+    A = (
+        inner(grad(phi), grad(v_1)) * dx
+        - 1 / Lambda2 * nF(y_A(phi, p), y_C(phi, p), p) * v_1 * dx
+    ) + (
+        inner(grad(p), grad(v_2)) * dx
+        + 1 / a2 * nF(y_A(phi, p), y_C(phi, p), p) * dot(grad(phi), grad(v_2)) * dx
+    )
+    F = A
+
+    # Define Nonlinear Problem
+    problem = NonlinearProblem(F, u, bcs=bcs)
+
+    # Define Newton Solver and solver settings
+    solver = NewtonSolver(MPI.COMM_WORLD, problem)
+    solver.convergence_criterion = "incremental"
+    solver.rtol = rtol
+    if relax_param != None:
+        solver.relaxation_parameter = relax_param
+    else:
+        if phi_right == phi_left:
+            solver.relaxation_parameter = 1.0
+        else:
+            solver.relaxation_parameter = 1/(np.abs(phi_right-phi_left)**(5/4))
+    solver.max_it = max_iter
+    solver.report = True
+
+    # Solve the problem
+    log.set_log_level(log.LogLevel.INFO)
+    n, converged = solver.solve(u)
+    assert (converged)
+    print(f"Number of interations: {n:d}")
+
+    # Split the mixed function space into the individual components    
+    phi, p = u.split()
+    
+    # Return the solution
+    if return_type=='Vector':
+        x_vals = np.array(msh.geometry.x[:,0])
+        phi_vals = np.array(u.sub(0).collapse().x.array)
+        p_vals = np.array(u.sub(1).collapse().x.array)
+
+        # Calculate the atomic fractions
+        D_A = y_A_R / np.exp(-(solvation + 1) * a2 * p_right - z_A * phi_right)
+        y_A_vals = D_A * np.exp(-(solvation + 1) * a2 * p_vals - z_A * phi_vals)
+    
+        D_C = y_C_R / np.exp(-(solvation + 1) * a2 * p_right - z_C * phi_right)
+        y_C_vals = D_C * np.exp(-(solvation + 1) * a2 * p_vals - z_C * phi_vals)
+        
+        return y_A_vals, y_C_vals, phi_vals, p_vals, x_vals
+    
+if __name__ == '__main__':
+    # Define the parameters
+    phi_left = 5.0
+    phi_right = 0.0
+    p_right = 0.0
+    y_A_R = 1/3
+    y_C_R = 1/3
+    z_A = -1.0
+    z_C = 1.0
+    K = 'incompressible'
+    Lambda2 = 8.553e-6
+    a2 = 7.5412e-4
+    number_cells = 1024
+    relax_param = .1
+    rtol = 1e-4
+    max_iter = 500
+    
+    # Solve the system
+    y_A, y_C, phi, p, x = solve_System_2eq(phi_left, phi_right, p_right, z_A, z_C, y_A_R, y_C_R, K, Lambda2, a2, number_cells, relax_param=relax_param, x0=0, x1=1, refinement_style='uniform', return_type='Vector', max_iter=max_iter, rtol=rtol)
+    
+    # Plot the solution
+    plt.plot(x, phi)
+    plt.xlim(0,0.05)
+    plt.grid()
+    plt.xlabel('x [-]')
+    plt.ylabel('$\\varphi$  [-]')
+    plt.show()
+    
+    plt.plot(x, y_A, '--', color='tab:blue', label='$y_A$')
+    plt.plot(x, y_C, '-', color='tab:blue', label='$y_C$')
+    plt.plot(x, 1 - y_A - y_C, ':', color='tab:blue', label='$y_S$')
+    plt.xlim(0,0.05)
+    plt.legend()
+    plt.grid()
+    plt.xlabel('x [-]')
+    plt.ylabel('$y_\\alpha$ [-]')
+    plt.show()
+    
+    plt.plot(x, p)
+    plt.xlim(0,0.05)
+    plt.grid()
+    plt.xlabel('x [-]')
+    plt.ylabel('$p$ [-]')
+    plt.show()
diff --git a/build/lib/Bsc-ElectrolyteModels/Eq04.py b/build/lib/Bsc-ElectrolyteModels/Eq04.py
new file mode 100644
index 0000000..4856d84
--- /dev/null
+++ b/build/lib/Bsc-ElectrolyteModels/Eq04.py
@@ -0,0 +1,358 @@
+'''
+Jan Habscheid
+Jan.Habscheid@rwth-aachen.de
+
+This script implements the fenics solver for a ternary electrolyte (N=3, A,C,S)
+'''
+
+import numpy as np
+from mpi4py import MPI
+from dolfinx import mesh, fem, log
+from dolfinx.fem.petsc import NonlinearProblem
+from dolfinx.nls.petsc import NewtonSolver
+from ufl import TestFunctions, split, dot, grad, dx, inner, ln, Mesh
+from basix.ufl import element, mixed_element
+import matplotlib.pyplot as plt
+
+# Define mesh
+def create_refined_mesh(refinement_style:str, number_cells:int) -> Mesh:
+    '''
+    Creates a one-dimensional mesh with a refined region at the left boundary
+
+    Parameters
+    ----------
+    refinement_style : str
+        How the mesh should be refined. Options are 'log', 'hard_log', 'hard_hard_log'
+    number_cells : int
+        Number of cells in the mesh
+
+    Returns
+    -------
+    Mesh
+        One-dimensional mesh, ready for use in FEniCSx
+    '''
+    if refinement_style == 'log':
+        coordinates_np = (np.logspace(0, 1, number_cells+1) - 1) / 9
+    elif refinement_style == 'hard_log':
+        coordinates_np1 = (np.logspace(0,1,int(number_cells*0.9)+1,endpoint=False)-1)/9 * 0.1
+        coordinates_np2 = 0.1 + (np.logspace(0,1,int(number_cells*0.1)+1)-1)/9 * 0.9
+        coordinates_np = np.concatenate((coordinates_np1, coordinates_np2), axis=0)
+    elif refinement_style == 'hard_hard_log':
+        coordinates_np1 = (np.logspace(0,1,int(number_cells*0.9)+1,endpoint=False)-1)/9 * 0.004
+        coordinates_np2 = 0.004 + (np.logspace(0,1,int(number_cells*0.1)+1)-1)/9 * 0.996
+        coordinates_np = np.concatenate((coordinates_np1, coordinates_np2), axis=0)
+    num_vertices = len(coordinates_np)
+    num_cells = num_vertices - 1
+    cells_np = np.column_stack((np.arange(num_cells), np.arange(1, num_cells+1)))
+    gdim = 1
+    shape = 'interval' # 'interval', 'triangle', 'quadrilateral', 'tetrahedron', 'hexahedron'
+    degree = 1
+    domain = Mesh(element("Lagrange", shape, 1, shape=(1,)))
+    coordinates_np_ = []
+    [coordinates_np_.append([coord]) for coord in coordinates_np]
+    msh = mesh.create_mesh(MPI.COMM_WORLD, cells_np, coordinates_np_, domain)
+    return msh
+
+def solve_System_4eq(phi_left:float, phi_right:float, p_right:float, z_A:float, z_C:float, y_A_R:float, y_C_R:float, K:float|str, Lambda2:float, a2:float, number_cells:int, solvation:float = 0, PoissonBoltzmann:bool=False, relax_param:float=None, x0:float=0, x1:float=1, refinement_style:str='uniform', return_type:str='Scalar', rtol:float=1e-8, max_iter:float=500):
+    '''
+    Solve the dimensionless system of equations presented in: Numerical Treatment of a Thermodynamically Consistent Electrolyte Model, B.Sc. Thesis Habscheid 2024
+
+    System of equations:
+        λ²Δ φ =−L²n^F
+
+        a²∇p=−n^F∇ φ
+
+        div(J_A)=0
+
+        div(J_C)=0
+
+    with φ the electric potential, p the pressure, n^F the total free charge density, J_α the diffusion fluxes of species α, λ² a dimensionless parameter, L²=1, a² a dimensionless parameter, N the number of species, and α the species index.
+
+    ! If the Newton solver diverges, you may try to reduce the relaxation parameter.
+
+    Parameters
+    ----------
+    phi_left : float
+        Value of φ at the left boundary
+    phi_right : float
+        Value of φ at the right boundary
+    p_right : float
+        Value of p at the right boundary
+    z_A : float
+        Charge number of species A
+    z_C : float
+        Charge number of species C
+    y_A_R : float
+        Atomic fractions of species A at right boundary
+    y_C_R : float
+        Atomic fractions of species C at right boundary
+    K : float | str
+        Dimensioness bulk modulus of the electrolyte. If 'incompressible', the system is solved for an incompressible electrolyte
+    Lambda2 : float
+        Dimensionless parameter
+    a2 : float
+        Dimensionless parameter
+    number_cells : int
+        Number of cells in the mesh
+    solvation : float, optional
+        solvation number, by default 0
+    PoissonBoltzmann : bool, optional
+        Solve classical Nernst-Planck model with the use of the Poisson-Boltzmann formulation if True, else solve the presented model by Dreyer, Guhlke, Müller, by default False
+    relax_param : float, optional
+        Relaxation parameter for the Newton solver
+        xₙ₊₁ = γ xₙ f(xₙ)/f'(xₙ) with γ the relaxation parameter
+        , by default None -> Determined automatically
+    x0 : float, optional
+        Left boundary of the domain, by default 0
+    x1 : float, optional
+        Right boundary of the domain, by default 1
+    refinement_style : str, optional
+        Specify for refinement towards zero
+        Options are 'uniform', 'log', 'hard_log', 'hard_hard_log' by default 'uniform'
+    return_type : str, optional
+        'Vector' or 'Scalar', 'Scalar' returns dolfinx.fem type and 'Vector' numpy arrays of the solution, by default 'Scalar'
+    rtol : float, optional
+        Relative tolerance for Newton solver, by default 1e-8
+    max_iter : float, optional
+        Maximum number of Newton iterations, by default 500
+
+    Returns
+    -------
+    y_A, y_C, phi, p, msh
+        Returns atomic fractions for species A and C, electric potential, pressure, and the mesh
+        If return_type is 'Vector', the solution is returned as numpy arrays
+    '''
+    # Define boundaries of the domain
+    x0 = 0
+    x1 = 1
+
+    # Define boundaries for the boundary conditions
+    def Left(x):
+        return np.isclose(x[0], x0)
+
+    def Right(x):
+        return np.isclose(x[0], x1)
+    
+    # Create mesh
+    if refinement_style == 'uniform':
+        msh = mesh.create_unit_interval(MPI.COMM_WORLD, number_cells, dtype=np.float64)
+    else:
+        msh = create_refined_mesh(refinement_style, number_cells)
+
+    # Define Finite Elements
+    CG1_elem = element('Lagrange', msh.basix_cell(), 1)
+
+    # Define Mixed Function Space
+    W_elem = mixed_element([CG1_elem, CG1_elem, CG1_elem, CG1_elem])
+    W = fem.functionspace(msh, W_elem)
+
+    # Define Trial- and Testfunctions
+    u = fem.Function(W)
+    y_A, y_C, phi, p = split(u)
+    (v_A, v_C, v_1, v_2) = TestFunctions(W)
+
+    # Collapse function space for bcs
+    W0, _ = W.sub(0).collapse()
+    W1, _ = W.sub(1).collapse()
+    W2, _ = W.sub(2).collapse()
+    W3, _ = W.sub(3).collapse()
+
+    # Define boundary conditions values
+    def phi_left_(x):
+        return np.full_like(x[0], phi_left)
+    def phi_right_(x):
+        return np.full_like(x[0], phi_right)
+    def p_right_(x):
+        return np.full_like(x[0], p_right)
+    def y_A_right_(x):
+        return np.full_like(x[0], y_A_R)
+    def y_C_right_(x):
+        return np.full_like(x[0], y_C_R)
+
+    # Interpolate bcs functions
+    phi_left_bcs = fem.Function(W2)
+    phi_left_bcs.interpolate(phi_left_)
+    phi_right_bcs = fem.Function(W2)
+    phi_right_bcs.interpolate(phi_right_)
+    p_right_bcs = fem.Function(W3)
+    p_right_bcs.interpolate(p_right_)
+    y_A_right_bcs = fem.Function(W0)
+    y_A_right_bcs.interpolate(y_A_right_)
+    y_C_right_bcs = fem.Function(W1)
+    y_C_right_bcs.interpolate(y_C_right_)
+
+    # Identify dofs for boundary conditions
+    # Define boundary conditions
+    facet_left_dofs = fem.locate_dofs_geometrical((W.sub(2), W.sub(2).collapse()[0]), Left)
+    facet_right_dofs = fem.locate_dofs_geometrical((W.sub(2), W.sub(2).collapse()[0]), Right)
+    bc_left_phi = fem.dirichletbc(phi_left_bcs, facet_left_dofs, W.sub(2))
+    bc_right_phi = fem.dirichletbc(phi_right_bcs, facet_right_dofs, W.sub(2))
+
+    facet_right_dofs = fem.locate_dofs_geometrical((W.sub(3), W.sub(3).collapse()[0]), Right)
+    bc_right_p = fem.dirichletbc(p_right_bcs, facet_right_dofs, W.sub(3))
+
+    facet_right_dofs = fem.locate_dofs_geometrical((W.sub(0), W.sub(0).collapse()[0]), Right)
+    bc_right_y_A = fem.dirichletbc(y_A_right_bcs, facet_right_dofs, W.sub(0))
+
+    facet_right_dofs = fem.locate_dofs_geometrical((W.sub(1), W.sub(1).collapse()[0]), Right)
+    bc_right_y_C = fem.dirichletbc(y_C_right_bcs, facet_right_dofs, W.sub(1))
+
+    # Combine boundary conditions into list
+    bcs = [bc_left_phi, bc_right_phi, bc_right_p, bc_right_y_A, bc_right_y_C]
+        
+    
+
+    # Define variational problem
+    if K == 'incompressible':
+        # total free charge density
+        def nF(y_A, y_C):
+            return (z_C * y_C + z_A * y_A)
+        
+        # Diffusion fluxes for species A and C
+        def J_A(y_A, y_C, phi, p):
+            return grad(ln(y_A) + a2 * (p - 1) * (solvation + 1) + z_A * phi)
+            # return grad(ln(y_A) + a2 * (p - 1) - solvation * ln(1-y_A-y_C) + z_A * phi)
+        
+        def J_C(y_A, y_C, phi, p):
+            return grad(ln(y_C) + a2 * (p - 1) * (solvation + 1) + z_C * phi)
+            # return grad(ln(y_C) + a2 * (p - 1) - solvation * ln(1-y_A-y_C) + z_C * phi)
+        
+        # Variational Form
+        A = (
+            inner(grad(phi), grad(v_1)) * dx
+            - 1 / Lambda2 * nF(y_A, y_C) * v_1 * dx
+        ) + (
+            inner(grad(p), grad(v_2)) * dx
+            + 1 / a2 * nF(y_A, y_C) * dot(grad(phi), grad(v_2)) * dx
+        ) + (
+            inner(J_A(y_A, y_C, phi, p), grad(v_A)) * dx
+            + inner(J_C(y_A, y_C, phi, p), grad(v_C)) * dx
+        )
+        if PoissonBoltzmann:
+            A += (
+                inner(grad(- a2 * (p - 1) * (solvation + 1)), grad(v_A)) * dx
+                + inner(grad(- a2 * (p - 1) * (solvation + 1)), grad(v_C)) * dx
+            )
+    else: 
+        # total number density
+        def n(p):
+            return (p-1)/K + 1
+        
+        # total free charge density
+        def nF(y_A, y_C, p):
+            return (z_C * y_C + z_A * y_A) * n(p)
+        
+        # Diffusion fluxes for species A and C
+        def J_A(y_A, y_C, phi, p):
+            return ln(y_A) + a2 * (solvation + 1) * K * ln(1 + 1/K * (p-1)) + z_A * phi
+        
+        def J_C(y_A, y_C, phi, p):
+            return ln(y_C) + a2 * (solvation + 1)* K * ln(1 + 1/K * (p-1)) + z_C * phi
+
+        A = (
+            inner(grad(phi), grad(v_1)) * dx
+            - 1 / Lambda2 * nF(y_A, y_C, p) * v_1 * dx
+        ) + (
+            inner(grad(p), grad(v_2)) * dx
+            + 1 / a2 * nF(y_A, y_C, p) * dot(grad(phi), grad(v_2)) * dx
+        ) + (
+            inner(grad(J_A(y_A, y_C, phi, p)), grad(v_A)) * dx
+            + inner(grad(J_C(y_A, y_C, phi, p)), grad(v_C)) * dx
+        )
+    F = A
+
+    # Initialize initial guess for u
+    y_C_init = fem.Function(W1)
+    y_A_init = fem.Function(W0)
+    y_C_init.interpolate(lambda x: np.full_like(x[0], y_C_R))
+    y_A_init.interpolate(lambda x: np.full_like(x[0], y_A_R))
+
+    with u.vector.localForm() as u_loc:
+        u_loc.set(0)
+    u.sub(0).interpolate(y_A_init)
+    u.sub(1).interpolate(y_C_init)
+
+    # Define Nonlinear Problem
+    problem = NonlinearProblem(F, u, bcs=bcs)
+
+    # Define Newton Solver and solver settings
+    solver = NewtonSolver(MPI.COMM_WORLD, problem)
+    solver.convergence_criterion = "incremental"
+    solver.rtol = rtol
+    if relax_param != None:
+        solver.relaxation_parameter = relax_param
+    else:
+        if phi_right == phi_left:
+            solver.relaxation_parameter = 1.0
+        else:
+            solver.relaxation_parameter = 1/(np.abs(phi_right-phi_left)**(5/4))
+    solver.max_it = max_iter
+    solver.report = True
+
+    # Solve the problem
+    log.set_log_level(log.LogLevel.INFO)
+    n, converged = solver.solve(u)
+    assert (converged)
+    print(f"Number of interations: {n:d}")
+
+    # Split the mixed function space into the individual components    
+    y_A, y_C, phi, p = u.split()
+    
+    # Return the solution
+    if return_type=='Vector':
+        x_vals = np.array(msh.geometry.x[:,0])
+        y_A_vals = np.array(u.sub(0).collapse().x.array)
+        y_C_vals = np.array(u.sub(1).collapse().x.array)
+        phi_vals = np.array(u.sub(2).collapse().x.array)
+        p_vals = np.array(u.sub(3).collapse().x.array)
+        
+        return y_A_vals, y_C_vals, phi_vals, p_vals, x_vals
+    elif return_type=='Scalar':
+        return y_A, y_C, phi, p, msh
+    
+    
+if __name__ == '__main__':
+    # Define the parameters
+    phi_left = 10.0
+    phi_right = 0.0
+    p_right = 0.0
+    y_A_R = 0.01#1/3
+    y_C_R = 0.01#1/3
+    z_A = -1.0
+    z_C = 1.0
+    K = 'incompressible'
+    Lambda2 = 8.553e-6
+    a2 = 7.5412e-4
+    solvation = 0
+    number_cells = 1024
+    relax_param = .1
+    rtol = 1e-4
+    max_iter = 500
+    
+    # Solve the system
+    y_A, y_C, phi, p, x = solve_System_4eq(phi_left, phi_right, p_right, z_A, z_C, y_A_R, y_C_R, K, Lambda2, a2, number_cells, solvation=solvation,  relax_param=relax_param, x0=0, x1=1, refinement_style='uniform', return_type='Vector', max_iter=max_iter, rtol=rtol)
+    
+    # Plot the solution
+    plt.plot(x, phi)
+    plt.xlim(0,0.05)
+    plt.grid()
+    plt.xlabel('x [-]')
+    plt.ylabel('$\\varphi$  [-]')
+    plt.show()
+    
+    plt.plot(x, y_A, '--', color='tab:blue', label='$y_A$')
+    plt.plot(x, y_C, '-', color='tab:blue', label='$y_C$')
+    plt.plot(x, 1 - y_A - y_C, ':', color='tab:blue', label='$y_S$')
+    plt.xlim(0,0.05)
+    plt.legend()
+    plt.grid()
+    plt.xlabel('x [-]')
+    plt.ylabel('$y_\\alpha$ [-]')
+    plt.show()
+    
+    plt.plot(x, p)
+    plt.xlim(0,0.05)
+    plt.grid()
+    plt.xlabel('x [-]')
+    plt.ylabel('$p$ [-]')
+    plt.show()
diff --git a/build/lib/Bsc-ElectrolyteModels/EqN.py b/build/lib/Bsc-ElectrolyteModels/EqN.py
new file mode 100644
index 0000000..9b48ed1
--- /dev/null
+++ b/build/lib/Bsc-ElectrolyteModels/EqN.py
@@ -0,0 +1,324 @@
+'''
+Jan Habscheid
+Jan.Habscheid@rwth-aachen.de
+
+This script implements the fenics solver for the generic system of equations for N species
+'''
+
+import numpy as np
+from mpi4py import MPI
+from dolfinx import mesh, fem, log
+from dolfinx.fem.petsc import NonlinearProblem
+from dolfinx.nls.petsc import NewtonSolver
+from ufl import TestFunctions, split, dot, grad, dx, inner, ln, Mesh
+from basix.ufl import element, mixed_element
+import matplotlib.pyplot as plt
+
+# Define mesh
+def create_refined_mesh(refinement_style:str, number_cells:int) -> Mesh:
+    '''
+    Creates a one-dimensional mesh with a refined region at the left boundary
+
+    Parameters
+    ----------
+    refinement_style : str
+        How the mesh should be refined. Options are 'log', 'hard_log', 'hard_hard_log'
+    number_cells : int
+        Number of cells in the mesh
+
+    Returns
+    -------
+    Mesh
+        One-dimensional mesh, ready for use in FEniCSx
+    '''
+    if refinement_style == 'log':
+        coordinates_np = (np.logspace(0, 1, number_cells+1) - 1) / 9
+    elif refinement_style == 'hard_log':
+        coordinates_np1 = (np.logspace(0,1,int(number_cells*0.9)+1,endpoint=False)-1)/9 * 0.1
+        coordinates_np2 = 0.1 + (np.logspace(0,1,int(number_cells*0.1)+1)-1)/9 * 0.9
+        coordinates_np = np.concatenate((coordinates_np1, coordinates_np2), axis=0)
+    elif refinement_style == 'hard_hard_log':
+        coordinates_np1 = (np.logspace(0,1,int(number_cells*0.9)+1,endpoint=False)-1)/9 * 0.004
+        coordinates_np2 = 0.004 + (np.logspace(0,1,int(number_cells*0.1)+1)-1)/9 * 0.996
+        coordinates_np = np.concatenate((coordinates_np1, coordinates_np2), axis=0)
+    num_vertices = len(coordinates_np)
+    num_cells = num_vertices - 1
+    cells_np = np.column_stack((np.arange(num_cells), np.arange(1, num_cells+1)))
+    gdim = 1
+    shape = 'interval' # 'interval', 'triangle', 'quadrilateral', 'tetrahedron', 'hexahedron'
+    degree = 1
+    domain = Mesh(element("Lagrange", shape, 1, shape=(1,)))
+    coordinates_np_ = []
+    [coordinates_np_.append([coord]) for coord in coordinates_np]
+    msh = mesh.create_mesh(MPI.COMM_WORLD, cells_np, coordinates_np_, domain)
+    return msh
+
+def solve_System_Neq(phi_left:float, phi_right:float, p_right:float, z_alpha:list, y_R:list, K:float|str, Lambda2:float, a2:float, number_cells:int, solvation:float = 0, PoissonBoltzmann:bool=False, relax_param:float=None, x0:float=0, x1:float=1, refinement_style:str='uniform', return_type:str='Vector', rtol:float=1e-8, max_iter:float=500):
+    '''
+    Solve the dimensionless system of equations presented in: Numerical Treatment of a Thermodynamically Consistent Electrolyte Model, B.Sc. Thesis Habscheid 2024
+
+    System of equations:
+        λ²Δ φ =−L²n^F
+
+        a²∇p=−n^F∇ φ
+        
+        div(J_α)=0  α∈ {1,...,N−1}
+
+    with φ the electric potential, p the pressure, n^F the total free charge density, J_α the diffusion fluxes of species α, λ² a dimensionless parameter, L²=1, a² a dimensionless parameter, N the number of species, and α the species index.
+
+    ! If the Newton solver diverges, you may try to reduce the relaxation parameter.
+
+    Parameters
+    ----------
+    phi_left : float
+        Value of φ at the left boundary
+    phi_right : float
+        Value of φ at the right boundary
+    p_right : float
+        Value of p at the right boundary
+    z_alpha : list
+        Charge numbers for species α = 1,...,N-1
+    y_R : list
+        Atomic fractions at right boundary for species α = 1,...,N-1
+    K : float | str
+        Dimensioness bulk modulus of the electrolyte. If 'incompressible', the system is solved for an incompressible electrolyte
+    Lambda2 : float
+        Dimensionless parameter
+    a2 : float
+        Dimensionless parameter
+    number_cells : int
+        Number of cells in the mesh
+    solvation : float, optional
+        solvation number, not implemented yet, by default 0
+    PoissonBoltzmann : bool, optional
+        Solve classical Nernst-Planck model with the use of the Poisson-Boltzmann formulation if True, else solve the presented model by Dreyer, Guhlke, Müller, Not implemented yet, by default False
+    relax_param : float, optional
+        Relaxation parameter for the Newton solver
+        xₙ₊₁ = γ xₙ f(xₙ)/f'(xₙ) with γ the relaxation parameter
+        , by default None -> Determined automatically
+    x0 : float, optional
+        Left boundary of the domain, by default 0
+    x1 : float, optional
+        Right boundary of the domain, by default 1
+    refinement_style : str, optional
+        Specify for refinement towards zero
+        Options are 'uniform', 'log', 'hard_log', 'hard_hard_log' by default 'uniform'
+    return_type : str, optional
+        'Vector' or 'Scalar' (not implemented yet, should be implemented in a later version), 'Scalar' returns dolfinx.fem type and 'Vector' numpy arrays of the solution, by default 'Vector'
+    rtol : float, optional
+        Relative tolerance for Newton solver, by default 1e-8
+    max_iter : float, optional
+        Maximum number of Newton iterations, by default 500
+
+    Returns
+    -------
+    y_A, y_C, phi, p, msh
+        Returns atomic fractions for species A and C, electric potential, pressure, and the mesh
+        If return_type is 'Vector', the solution is returned as numpy arrays
+        Only return_type 'Vector' is implemented yet
+    '''
+    if solvation != 0: 
+        raise NotImplementedError('Solvation number not implemented yet')
+    if PoissonBoltzmann:
+        raise NotImplementedError('Poisson-Boltzmann not implemented yet')
+    # Define boundaries of the domain
+    x0 = 0
+    x1 = 1
+
+    # Define boundaries
+    def Left(x):
+        return np.isclose(x[0], x0)
+
+    def Right(x):
+        return np.isclose(x[0], x1)
+    
+    # Create mesh
+    if refinement_style == 'uniform':
+        msh = mesh.create_unit_interval(MPI.COMM_WORLD, number_cells, dtype=np.float64)
+    else:
+        msh = create_refined_mesh(refinement_style, number_cells)
+
+    # Define Finite Elements
+    CG1_elem = element('Lagrange', msh.basix_cell(), 1)
+
+    # Define Mixed Function Space
+    Elem_list = [CG1_elem, CG1_elem]
+    [Elem_list.append(CG1_elem) for _ in range(len(z_alpha))]
+    W_elem = mixed_element(Elem_list)
+    W = fem.functionspace(msh, W_elem)
+
+    # Define Trial- and Testfunctions
+    u = fem.Function(W)
+    my_TrialFunctions = split(u)
+    my_TestFunctions = TestFunctions(W)
+
+    phi, p = my_TrialFunctions[0], my_TrialFunctions[1]
+    v_1, v_2 = my_TestFunctions[0], my_TestFunctions[1]
+    y_alpha = my_TrialFunctions[2:]
+    v_alpha = my_TestFunctions[2:]
+
+    # Collapse function space for bcs
+    W_ = []
+    [W_.append(W.sub(i).collapse()[0]) for i in range(len(z_alpha)+2)]
+
+    # Define boundary conditions values
+    def phi_left_(x):
+        return np.full_like(x[0], phi_left)
+    def phi_right_(x):
+        return np.full_like(x[0], phi_right)
+    def p_right_(x):
+        return np.full_like(x[0], p_right)
+    
+    # Interpolate bcs functions
+    phi_left_bcs = fem.Function(W_[0])
+    phi_left_bcs.interpolate(phi_left_)
+    phi_right_bcs = fem.Function(W_[0])
+    phi_right_bcs.interpolate(phi_right_)
+    p_right_bcs = fem.Function(W_[1])
+    p_right_bcs.interpolate(p_right_)
+
+    # Identify dofs for boundary conditions
+    facet_left_dofs = fem.locate_dofs_geometrical((W.sub(0), W.sub(0).collapse()[0]), Left)
+    facet_right_dofs = fem.locate_dofs_geometrical((W.sub(0), W.sub(0).collapse()[0]), Right)
+    bc_left_phi = fem.dirichletbc(phi_left_bcs, facet_left_dofs, W.sub(0))
+    bc_right_phi = fem.dirichletbc(phi_right_bcs, facet_right_dofs, W.sub(0))
+
+    facet_right_dofs = fem.locate_dofs_geometrical((W.sub(1), W.sub(1).collapse()[0]), Right)
+    bc_right_p = fem.dirichletbc(p_right_bcs, facet_right_dofs, W.sub(1))
+
+    # Combine boundary conditions for electric potential and pressure into list
+    bcs = [bc_left_phi, bc_right_phi, bc_right_p]
+
+    # Repeat the same for the boundary conditoins for the atomic fractions
+    for i in range(len(z_alpha)):
+        y_right_bcs = fem.Function(W_[i+2])
+        def y_right_(x):
+            return np.full_like(x[0], y_R[i])
+        y_right_bcs.interpolate(y_right_)
+        facet_right_dofs = fem.locate_dofs_geometrical((W.sub(i+2), W.sub(i+2).collapse()[0]), Right)
+        bc_right_y = fem.dirichletbc(y_right_bcs, facet_right_dofs, W.sub(i+2))
+        bcs.append(bc_right_y)
+        
+    # Define variational problem
+    if K == 'incompressible':
+        # total free charge density
+        def nF(y_alpha):
+            nF = 0
+            for i in range(len(z_alpha)):
+                nF += z_alpha[i] * y_alpha[i]
+            return nF
+        
+        # Diffusion fluxes for species A and C
+        def J_alpha(y_alpha, alpha, phi, p):
+            mu_alpha = ln(y_alpha[alpha])
+            mu_S = ln(1 - sum(y_alpha))
+            return grad(mu_alpha - mu_S + z_alpha[alpha] * phi)
+        
+        # Variational Form
+        A = (
+            inner(grad(phi), grad(v_1)) * dx
+            - 1 / Lambda2 * nF(y_alpha) * v_1 * dx
+        ) + (
+            inner(grad(p), grad(v_2)) * dx
+            + 1 / a2 * nF(y_alpha) * dot(grad(phi), grad(v_2)) * dx
+        )
+        for alpha in range(len(z_alpha)):
+            A += (
+                inner(J_alpha(y_alpha, alpha, phi, p), grad(v_alpha[alpha])) * dx
+            )
+        if PoissonBoltzmann:
+            raise ValueError('Poisson-Boltzmann not implemented for incompressible systems')
+    else: 
+        raise ValueError('Only incompressible systems are implemented')
+    F = A
+
+    # Initialize initial guess for u
+    with u.vector.localForm() as u_loc:
+        u_loc.set(0)
+
+    # Initialize initial guess for u
+    for alpha in range(len(z_alpha)):
+        y_alpha_init = fem.Function(W_[alpha+2])
+        y_alpha_init.interpolate(lambda x: np.full_like(x[0], y_R[alpha]))
+        u.sub(alpha+2).interpolate(y_alpha_init)
+
+    # Define Nonlinear Problem
+    problem = NonlinearProblem(F, u, bcs=bcs)
+
+    # Define Newton Solver
+    solver = NewtonSolver(MPI.COMM_WORLD, problem)
+    solver.convergence_criterion = "incremental"
+    solver.rtol = rtol
+    if relax_param != None:
+        solver.relaxation_parameter = relax_param
+    else:
+        if phi_right == phi_left:
+            solver.relaxation_parameter = 1.0
+        else:
+            solver.relaxation_parameter = 1/(np.abs(phi_right-phi_left)**(5/4))
+    solver.max_it = max_iter
+    solver.report = True
+
+    
+    log.set_log_level(log.LogLevel.INFO)
+    n, converged = solver.solve(u)
+    assert (converged)
+    print(f"Number of (interations: {n:d}")
+
+    # Return the solution    
+    if return_type=='Vector':
+        x = np.array(msh.geometry.x[:,0])
+        phi = np.array(u.sub(0).collapse().x.array)
+        p = np.array(u.sub(1).collapse().x.array)
+        y = []
+        [y.append(u.sub(i+2).collapse().x.array) for i in range(len(z_alpha))]
+        y = np.array(y)    
+        return y, phi, p, x
+    
+    
+if __name__ == '__main__':
+    # Define the parameters
+    phi_left = 8.0
+    phi_right = 0.0
+    p_right = 0.0
+    y_R = [3/6, 1/6, 1/6]
+    z_alpha = [-1.0, 1.0, 2.0]
+    K = 'incompressible'
+    Lambda2 = 8.553e-6
+    a2 = 7.5412e-4
+    number_cells = 1024
+    relax_param = .05
+    rtol = 1e-4
+    max_iter = 2_500
+    refinement_style = 'hard_log'
+    return_type = 'Vector'
+    
+    # Solve the system
+    y, phi, p, x = solve_System_Neq(phi_left, phi_right, p_right, z_alpha, y_R, K, Lambda2, a2, number_cells, relax_param=relax_param, refinement_style=refinement_style, return_type=return_type, max_iter=max_iter, rtol=rtol)
+    
+    # Plot the solution
+    plt.figure()
+    plt.plot(x, phi)
+    plt.xlim(0,0.05)
+    plt.grid()
+    plt.xlabel('x [-]')
+    plt.ylabel('$\\varphi$ [-]')
+    plt.show()
+    
+    plt.figure()
+    plt.xlim(0,0.05)
+    plt.plot(x, p)
+    plt.grid()
+    plt.xlabel('x [-]')
+    plt.ylabel('$p$ [-]')
+    plt.show()
+
+    plt.figure()
+    for i in range(len(z_alpha)):
+        plt.plot(x, y[i], label=f'$y_{i}$')
+    plt.xlim(0,0.05)
+    plt.legend()
+    plt.grid()
+    plt.xlabel('x [-]')
+    plt.ylabel('$y_i$ [-]')
+    plt.show()
\ No newline at end of file
diff --git a/build/lib/Bsc-ElectrolyteModels/Helper_DoubleLayerCapacity.py b/build/lib/Bsc-ElectrolyteModels/Helper_DoubleLayerCapacity.py
new file mode 100644
index 0000000..e47b37e
--- /dev/null
+++ b/build/lib/Bsc-ElectrolyteModels/Helper_DoubleLayerCapacity.py
@@ -0,0 +1,411 @@
+'''
+Jan Habscheid
+Jan.Habscheid@rwth-aachen.de
+'''
+
+import numpy as np
+from scipy.optimize import fixed_point, fsolve
+
+
+# Helper functions
+def Phi_pot_center(Phi_pot:np.ndarray) -> np.ndarray:
+    '''
+    Returns vector with the center of the electric potential values.
+
+    Parameters
+    ----------
+    Phi_pot : np.ndarray
+        Input vector with electric potential values.
+
+    Returns
+    -------
+    np.ndarray
+        Vector with the center of the electric potential values.
+    '''
+    return (Phi_pot[1:] + Phi_pot[:-1]) / 2
+
+def dx(Phi_pot:np.ndarray) -> float:
+    '''
+    Returns the difference between the first two electric potential values.
+    
+    Assumes that the electric potential values are equally spaced.
+
+    Parameters
+    ----------
+    Phi_pot : np.ndarray
+        Input vector with electric potential values.
+
+    Returns
+    -------
+    float
+        Difference between the first two electric potential values.
+    '''
+    return Phi_pot[1] - Phi_pot[0]
+
+def C_dl(Q_DL:np.ndarray, Phi_pot:np.ndarray) -> np.ndarray:
+    '''
+    Double Layer Capacity
+
+    Parameters
+    ----------
+    Q_DL : np.ndarray
+        Charge of the system
+    Phi_pot : np.ndarray
+        Electric potential values
+
+    Returns
+    -------
+    np.ndarray
+        Double Layer Capacity
+    '''
+    return (Q_DL[1:] - Q_DL[:-1]) / dx(Phi_pot)
+
+def n(p:np.ndarray, K:str|float) -> np.ndarray:
+    '''
+    Calculates the total number density
+
+    Parameters
+    ----------
+    p : np.ndarray
+        Pressure
+    K : str | float
+        Bulk modulus, use 'incompressible' for an incompressible mixture
+
+    Returns
+    -------
+    np.ndarray
+        Total number density
+    '''
+    if K == 'incompressible':
+        return np.ones_like(p)
+    n_Dimensionless = (p-1) / K + 1
+    return n_Dimensionless
+
+def Q_num_(y_A:np.ndarray, y_C:np.ndarray, n:np.ndarray, x:np.ndarray, z_A:float=-1.0, z_C:float=1.0) -> float:
+    '''
+    Calculates the charge of the system
+
+    Q = ∫_Ω n^F dΩ
+
+    Parameters
+    ----------
+    y_A : np.ndarray
+        Anion fraction
+    y_C : np.ndarray
+        Cation fraction
+    n : np.ndarray
+        Total number density
+    x : np.ndarray
+        Spatial discretization
+    z_A : float, optional
+        Charge number of anions, by default -1.0
+    z_C : float, optional
+        Charge number of cations, by default 1.0
+
+    Returns
+    -------
+    float
+        Charge of the system
+    '''
+    nF_dimensionless = (z_C * y_C + z_A * y_A) * n
+    nF_int = -np.trapz(nF_dimensionless, x)
+    return nF_int
+
+def Q_num_dim(y_A:np.ndarray, y_C:np.ndarray, n:np.ndarray, x:np.ndarray, z_A:float, z_C:float, nR_m:float, e0:float, LR:float) -> float:
+    '''
+    Calculates the charge of the system
+
+    Q = ∫_Ω n^F dΩ
+
+    Parameters
+    ----------
+    y_A : np.ndarray
+        Anion fraction
+    y_C : np.ndarray
+        Cation fraction
+    n : np.ndarray
+        Total number density
+    x : np.ndarray
+        Spatial discretization
+    z_A : float, optional
+        Charge number of anions, by default -1.0
+    z_C : float, optional
+        Charge number of cations, by default 1.0
+    nR_m : float
+        Reference number density in 1/m^3
+    e0 : float
+        Dielectric constant
+    LR : float
+        Reference length in m
+
+    Returns
+    -------
+    float
+        Charge of the system
+    '''
+    Q_DL = Q_num_(y_A, y_C, n, x, z_A, z_C)
+    Q_DL *= nR_m * e0 * LR
+    Q_DL *= 1e+6 
+    Q_DL *= 1/(1e+4)
+    return Q_DL
+
+def Q_DL_dimless_ana(y_A_R:float, y_C_R:float, y_N_R:float, z_A:float, z_C:float, phi_L:float, phi_R:float, p_R:float, K:str|float, Lambda2:float, a2:float, solvation:float) -> float:
+    '''
+    Calculates charge of the system using the analytical method in dimensionless units
+
+    Q = λ^2(∂ₓ φᴸ − ∂ₓ  φᴿ)
+
+    Parameters
+    ----------
+    y_A_R : float
+        Value of anion fraction at the right boundary
+    y_C_R : float
+        Value of cation fraction at the right boundary
+    y_N_R : float
+        Value of neutral fraction at the right boundary
+    z_A : float
+        Charge number of anions
+    z_C : float
+        Charge number of cations
+    phi_L : float
+        Electric potential at the left boundary [V]
+    phi_R : float
+        Electric potential at the right boundary
+    p_R : float
+        Pressure at the right boundary
+    K : str | float
+        Bulk modulus, use 'incompressible' for an incompressible mixture
+    Lambda2 : float
+        Dimensionless parameter
+    a2 : float
+        Dimensionless parameter
+    solvation : float
+        Solvation number
+
+    Returns
+    -------
+    float
+        Charge of the system in dimensionless units
+    '''
+    if solvation != 0:
+        raise ValueError('Solvation number must be 0 for the analytical method')
+    z_N = 0
+    E_p = p_R
+    if K == 'incompressible':
+        # Assume E_p = p_R = 0        
+        D_A = y_A_R / (np.exp(-a2*p_R-z_A*phi_R))
+        D_C = y_C_R / (np.exp(-a2*p_R-z_C*phi_R))
+        D_N = y_N_R / (np.exp(-a2*p_R))
+
+        # Analytical method
+        E_p = p_R
+        CLambda_L = np.log(D_A * np.exp(-z_A * phi_L - E_p) + D_C * np.exp(-z_C * phi_L - E_p) + D_N * np.exp(-z_N * phi_L - E_p))
+
+        Lambda = np.sqrt(Lambda2)
+        Q_DL = (phi_L-phi_R) / np.abs(phi_L-phi_R) * Lambda * np.sqrt(2) * (np.sqrt(CLambda_L))
+        return Q_DL
+    else:
+        C_A = y_A_R / ((K + p_R  - 1)**(-1*a2*K)*np.exp(-z_A*phi_R))
+        C_C = y_C_R / ((K + p_R  - 1)**(-1*a2*K)*np.exp(-z_C*phi_R))
+        C_N = y_N_R / ((K + p_R  - 1)**(-1*a2*K)*np.exp(-z_N*phi_R))
+
+        CLambda_L = C_A * np.exp(-z_A*phi_L) + C_C * np.exp(-z_C*phi_L) + C_N
+
+        Left = np.sqrt((1/CLambda_L)**(-1/(a2*K)) + 1 - K - E_p)
+
+        Lambda = np.sqrt(Lambda2)
+        a = np.sqrt(a2)
+
+        Q_DL = (phi_L-phi_R) / np.abs(phi_L-phi_R) * Lambda * a * np.sqrt(2) * (Left)# - Right)
+        return Q_DL
+    raise ValueError('Invalid input for K')
+
+def Q_DL_dim_ana(y_A_R:float, y_C_R:float, y_N_R:float, z_A:float, z_C:float, phi_L:float, phi_R:float, p_R:float, K:str|float, Lambda2:float, a2:float, nR_m:float, e0:float, LR:float, solvation:float) -> float:
+    '''
+    Calculates charge of the system using the analytical method in dimensionless units
+
+    Q = λ^2(∂ₓ φᴸ − ∂ₓ  φᴿ)
+
+    Parameters
+    ----------
+    y_A_R : float
+        Value of anion fraction at the right boundary
+    y_C_R : float
+        Value of cation fraction at the right boundary
+    y_N_R : float
+        Value of neutral fraction at the right boundary
+    z_A : float
+        Charge number of anions
+    z_C : float
+        Charge number of cations
+    phi_L : float
+        Value of electric potential at the left boundary (dimensionless units)
+    phi_R : float
+        Value of electric potential at the right
+    p_R : float
+        Value of pressure at the right boundary
+    K : str | float
+        Bulk modulus, use 'incompressible' for an incompress
+    Lambda2 : float
+        Dimensionless parameter
+    a2 : float
+        Dimensionless parameter
+    nR_m : float
+        Reference number density in 1/m^3
+    e0 : float
+        Dielectric constant
+    LR : float
+        Reference length in m
+    solvation : float
+        Solvation number
+
+    Returns
+    -------
+    float
+        Charge of the system in µAs/cm³
+    '''
+    Q_DL = Q_DL_dimless_ana(y_A_R, y_C_R, y_N_R, z_A, z_C, phi_L, phi_R, p_R, K, Lambda2, a2, solvation)
+    Q_DL *= nR_m * e0 * LR
+    Q_DL *= 1e+6 
+    Q_DL *= 1/(1e+4)
+    return Q_DL
+
+
+
+def C_DL_dimless_ana(y_A_R:float, y_C_R:float, y_N_R:float, z_A:float, z_C:float, phi_L:float, phi_R:float, p_R:float, K:str|float, Lambda2:float, a2:float, solvation:float) -> float:
+    '''
+    Calculates the double layer capacity of the system using the analytical method in dimensionless units
+
+    C_dl = ∂Q/∂ φᴸ
+
+    Parameters
+    ----------
+    y_A_R : float
+        Value of anion fraction at the right boundary
+    y_C_R : float
+        Value of cation fraction at the right boundary
+    y_N_R : float
+        Value of neutral fraction at the right boundary
+    z_A : float
+        Charge number of anions
+    z_C : float
+        Charge number of cations
+    phi_L : float
+        Electric potential at the left boundary [V]
+    phi_R : float
+        Electric potential at the right boundary
+    p_R : float
+        Pressure at the right boundary
+    K : str | float
+        Bulk modulus, use 'incompressible' for an incompressible mixture
+    Lambda2 : float
+        Dimensionless parameter
+    a2 : float
+        Dimensionless parameter
+    solvation : float
+        Solvation number
+
+    Returns
+    -------
+    float
+        Double layer capacity of the system in dimensionless units
+    '''
+    if solvation != 0:
+        raise ValueError('Solvation number must be 0 for the analytical method')
+    z_N = 0
+    E_p = p_R
+    if K == 'incompressible':
+        # Assume E_p = p_R = 0        
+        D_A = y_A_R / (np.exp(-a2*p_R-z_A*phi_R))
+        D_C = y_C_R / (np.exp(-a2*p_R-z_C*phi_R))
+        D_N = y_N_R / (np.exp(-a2*p_R))
+
+        CLambda_L = np.log(D_A * np.exp(-z_A * phi_L - E_p * a2) + D_C * np.exp(-z_C * phi_L - E_p * a2) + D_N * np.exp(-z_N * phi_L - E_p * a2))
+
+        xi_CLambda_L = D_A * np.exp(-z_A * phi_L - E_p * a2) + D_C * np.exp(-z_C * phi_L - E_p * a2) + D_N * np.exp(-z_N * phi_L - E_p * a2)
+        dxi_CLambda_L = - D_A * z_A * np.exp(-z_A * phi_L - E_p * a2) - D_C * z_C * np.exp(-z_C * phi_L - E_p * a2) - D_N * z_N * np.exp(-z_N * phi_L - E_p * a2)
+
+        Lambda = np.sqrt(Lambda2)
+
+        PreTerm = (phi_L-phi_R) / np.abs(phi_L-phi_R) * Lambda * np.sqrt(2)
+        DerivedTerm = dxi_CLambda_L / (2 * xi_CLambda_L * np.sqrt(np.log(xi_CLambda_L)))
+        
+        return PreTerm * DerivedTerm
+    else:
+        C_A = y_A_R / ((K + p_R  - 1)**(-1*a2*K)*np.exp(-z_A*phi_R))
+        C_C = y_C_R / ((K + p_R  - 1)**(-1*a2*K)*np.exp(-z_C*phi_R))
+        C_N = y_N_R / ((K + p_R  - 1)**(-1*a2*K)*np.exp(-z_N*phi_R))
+        
+        z = 1 - K - E_p
+        y = 1/(a2*K)
+
+        CLambda = C_A * np.exp(-z_A*phi_L) + C_C * np.exp(-z_C*phi_L) + C_N * np.exp(-z_N*phi_L)
+        dClambda = -C_A * z_A * np.exp(-z_A*phi_L) - C_C * z_C * np.exp(-z_C*phi_L) - C_N * z_N * np.exp(-z_N*phi_L)
+
+        Lambda = np.sqrt(Lambda2)
+        a = np.sqrt(a2)
+
+        DerivedTerm = y * CLambda**(y-1) * dClambda / (2 * np.sqrt(CLambda**y + z))
+
+        PreTerm = (phi_L-phi_R) / np.abs(phi_L-phi_R) * Lambda * a * np.sqrt(2)
+
+        return PreTerm * DerivedTerm
+    raise ValueError('Invalid input for K')
+
+
+
+def C_DL_dim_ana(y_A_R:float, y_C_R:float, y_N_R:float, z_A:float, z_C:float, phi_L:float, phi_R:float, p_R:float, K:str|float, Lambda2:float, a2:float, nR_m:float, e0:float, LR:float, k:float, T:float, solvation:float) -> float:
+    '''
+    Calculates the double layer capacity of the system using the analytical method in dimensionless units
+
+    C_dl = ∂Q/∂ φᴸ
+
+    Parameters
+    ----------
+    y_A_R : float
+        Value of anion fraction at the right boundary
+    y_C_R : float
+        Value of cation fraction at the right boundary
+    y_N_R : float
+        Value of neutral fraction at the right boundary
+    z_A : float
+        Charge number of anions
+    z_C : float
+        Charge number of cations
+    phi_L : float
+        Value of electric potential at the left boundary (dimensionless units)
+    phi_R : float
+        Value of electric potential at the right
+    p_R : float
+        Value of pressure at the right boundary
+    K : str | float
+        Bulk modulus, use 'incompressible' for an incompress
+    Lambda2 : float
+        Dimensionless parameter
+    a2 : float
+        Dimensionless parameter
+    nR_m : float
+        Reference number density in 1/m^3
+    e0 : float
+        Dielectric constant
+    LR : float
+        Reference length in m
+    k : float
+        Boltzmann constant
+    T : float
+        Temperature
+    solvation : float
+        Solvation number
+
+    Returns
+    -------
+    float
+        Double layer capacity of the system in µAs/cm²
+    '''
+    C_DL = C_DL_dimless_ana(y_A_R, y_C_R, y_N_R, z_A, z_C, phi_L, phi_R, p_R, K, Lambda2, a2, solvation)
+    C_DL *= nR_m * e0 * LR
+    # ! ToDo
+    C_DL *= 1e+6
+    C_DL *= 1/(1e+4) 
+    C_DL *= 1 /(k*T/e0)
+    return C_DL
\ No newline at end of file
diff --git a/build/lib/Bsc-ElectrolyteModels/__init__.py b/build/lib/Bsc-ElectrolyteModels/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/dist/BscElectrolyteModels-1.0-py3-none-any.whl b/dist/BscElectrolyteModels-1.0-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..fd17b699cfa34864d347290b3d90d59d0c1e2287
GIT binary patch
literal 35361
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
PGVn6Qu`n>KZ3XcFg(7wV

literal 0
HcmV?d00001

diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..7fd26b9
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools"]
+build-backend = "setuptools.build_meta"
\ No newline at end of file
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..d38a8f8
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,47 @@
+[metadata]
+name = BScElectrolytemodels
+version = attr: 1.0
+author = Jan Habscheid, Manuel Torrilhon, Lambert Theisen
+author_email = Jan.Habscheid@rwth-aachen.de, lambert.theisen@rwth-aachen.de, mt@mathcces.rwth-aachen.de 
+description = A placeholder for the description
+long_description = file: README.md
+long_description_content_type = text/markdown
+url = https://git.rwth-aachen.de/JanHab/Bsc-Electrolytemodels
+keywords = fenics-project, Battery Simulation, finite element method
+license = GNU General Public License v3.0 or later
+classifiers =
+    License :: OSI Approved :: GNU General Public License v3 (GPLv3)
+    Programming Language :: Python :: 3
+
+[options]
+package_dir=
+    =src
+packages = find:
+zip_safe = True
+python_requires == 3.12.3
+include_package_data = True
+install_requires =
+    pyvista == 0.43.10 
+    numpy == 1.26.4 
+    scipy == 1.14.0 
+
+[options.packages.find]
+where=src
+
+[options.entry_points]
+console_scripts = 
+    my-example-utility = example.example_module:main
+
+[options.extras_require]
+notebook = jupyter >=1.0.0
+tests = pytest == 8.3.3
+docs = 
+    sphinx == 7.3.7
+    myst-parser == 4.0.0
+    sphinx-copybotton == 0.5.2
+    sphinx_rtd_theme == 3.0.1
+build = build >= 0.7.0
+dev = 
+    BScElectrolytemodels[tests]
+    BScElectrolytemodels[docs]
+    BScElectrolytemodels[build]
\ No newline at end of file
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..5d16151
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,22 @@
+from setuptools import setup, find_packages
+
+setup(
+    name="BscElectrolyteModels",
+    version="1.0",
+    description="A description is yet to follow",
+    url="https://git.rwth-aachen.de/JanHab/Bsc-ElectrolyteModels",
+    author="Jan Habscheid, Lambert Theisen, Manuel Torrilhon",
+    author_email="Jan.Habscheid@rwth-aachen.de, lambert.theisen@rwth-aachen.de, mt@mathcces.rwth-aachen.de",
+    packages=["Bsc-ElectrolyteModels"],
+    package_dir={"Bsc-ElectrolyteModels":"src"},
+    package_data={"Bsc-ElectrolyteModels": ["tests/*"]},
+    python_requires="==3.12.3",
+    install_requires=[
+        "pyvista == 0.43.10",
+        "numpy == 1.26.4",
+        "scipy == 1.14.0"
+    ],
+    setup_requires=["pytest-runner"],
+    tests_require=["pytest>=7.4.0"],
+    test_suite="tests"
+)
diff --git a/tests/__pycache__/__init__.cpython-312.pyc b/tests/__pycache__/__init__.cpython-312.pyc
index 089662da0b56caba69f0501d02dac24686b4e462..651390ebc6f1c4a594785796f33eaf39a8f1de6a 100644
GIT binary patch
delta 53
zcmZ3$SkHBumzRryfq`MqtchGE3Uc~I`S~UK#rZj9sYUuFsl_G5`tk9Zd6^~g@p=W7
Jw<gvr0sya~5*+{l

delta 86
zcmb<lz{qu)mzRryfq_A!VIr4_qrHAcer~FMR$`vMOMY@`Zfaghv3`1HiGEUXvTkZl
pYH~?YeokdcYHof?YEH3!NosLPv3`7fW?p7Ve7s&k<*$ixiU5`^9yb60

diff --git a/tests/__pycache__/test_ElectrolyticDiode.cpython-312-pytest-8.3.3.pyc b/tests/__pycache__/test_ElectrolyticDiode.cpython-312-pytest-8.3.3.pyc
index aebed3727349670ee4178aee4a98d1060dad63ca..75443412202ab6efa782e9dc013bf0d7a93ba147 100644
GIT binary patch
delta 46
zcmcaKk#XZhMy}Jmyj%<n3=Df_ZRDyD;nmSE%Fi#+FV4>?OD)>GLB!RV@z&&T?souO
CN)W05

delta 79
zcmdluk@3<*My}Jmyj%<n3=C`9HgZ*n==thr<maa9XC>z8yW}UA=BDPA6zivFmgpxH
jC+nu>q$ZaX<>yqEq~_+Qq~;WF?iX=2X8bkzs{0)PBa<CL

diff --git a/tests/__pycache__/test_Eq02.cpython-312-pytest-8.3.3.pyc b/tests/__pycache__/test_Eq02.cpython-312-pytest-8.3.3.pyc
index df145f680fec694c6c644d8d8fdd81d57546a1f8..d6ac38f5546ba664255fcc939cd984fec4472e78 100644
GIT binary patch
delta 46
zcmaDbfpPx?My}Jmyj%<n3=Df_ZRBba=9Skk%Fi#+FV4>?OD)>GOPJY&@z&&h?u!6j
C{SX!a

delta 79
zcmdl#f$_lvMy}Jmyj%<n3=9hzH*z%z>pAFW<maa9XC>z8yW}UA=BDPA6zivFmgpxH
jC+nu>q$ZaX<>yqEq~_+Qq~;WFo+-?1!uV_QT=zu)BjFsJ

diff --git a/tests/__pycache__/test_Eq04.cpython-312-pytest-8.3.3.pyc b/tests/__pycache__/test_Eq04.cpython-312-pytest-8.3.3.pyc
index 389b1d06261f49dbfb4ffe9d76c7efeda9f2ad47..bfc8a082ed7595e3d98f6f3f974a4be8c0472035 100644
GIT binary patch
delta 46
zcmaDbfpPx?My}Jmyj%<n3=Df_ZRBba=9Skk%Fi#+FV4>?OD)>GOPJY&@z&&h?u!6j
C{SX!a

delta 79
zcmdl#f$_lvMy}Jmyj%<n3=9(+H*z%z>pAFW<maa9XC>z8yW}UA=BDPA6zivFmgpxH
jC+nu>q$ZaX<>yqEq~_+Qq~;WFo+-?1!uV_QT=zu)AR!!$

diff --git a/tests/__pycache__/test_EqN.cpython-312-pytest-8.3.3.pyc b/tests/__pycache__/test_EqN.cpython-312-pytest-8.3.3.pyc
index 6316e86eb0c6a2b14ab1657d500b84b1b8dfdab3..48cd69033b4fac8207b44760ff99d7ef78e8235a 100644
GIT binary patch
delta 44
zcmbOg_%nd(G%qg~0|NuYo>?2YrVH@O=@;eam*^Mg=ai)uZ9XqxDb9FnGN;Bw07D%P
A-~a#s

delta 77
zcmewvFe{MjG%qg~0|Ns?cgseu=>mH8`WgATsrp%odHOE-$)&lec_qdA>6s<^NyW*!
hsX3|1B}Mr;l_jaU`6;P6#hcd&Sc)_Ln*2h2A^`Z198&-Q

diff --git a/tests/__pycache__/test_Helper_DoubleLayerCapacity.cpython-312-pytest-8.3.3.pyc b/tests/__pycache__/test_Helper_DoubleLayerCapacity.cpython-312-pytest-8.3.3.pyc
index 3f329ce080859a5eda5164959c5001f4000d54fa..109a7a873b2b538ea6e694f0006e8c569c1bab68 100644
GIT binary patch
delta 162
zcmeDB!g%pBBiCtOUM>a(28KPeHgXB7^P1`x<>!~^7w6}cr4~*0RQF)~FnN-?Ci68h
z&B+;IvXdXEFOy~v*ZLsFz{}s@dP7jS!RrpM&=lh-6_ahR@hVPUu2Ig+z^AlXN%NTw
u<KD@fVc}4%=Vc+<q+~9zh~1EtzrZ4eqA@D`Dp;d&M3e&Kt<8NEHH-i=g*HF{

delta 219
zcmccknX&5&BiCtOUM>a(28Ogr8@UA4^}_Ts@^e%5vl8?4UGkGlb5rw5iuKboOZ1b9
zlXX*bQj<%H@^dOnQgicDQgezYYp8oL{+V2;uE}v(O!E^12dm`dx$1`%Iann>h%xZ;
zH@Myq6mIak!z(n!cuK`&+snL)pBR`}YZ)h3Ym~Eq7@NOpJkw!3Ir&a#ILrvO$#d0Z
zCkKaZQs!V)`yj?3C3AsA?1rrT1r{lEgKC&2D}`TWVPdUe+Wad#N`dj$=Fo~7MgYV;
BN$3Co

-- 
GitLab