Metadata-Version: 2.1
Name: rkstiff
Version: 0.0.3
Summary: Runge-Kutta adaptive-step solvers for nonlinear PDEs
Home-page: https://github.com/whalenpt/rkstiff
Author: Patrick Whalen
Author-email: whalenpt@gmail.com
License: UNKNOWN
Description: 
        # rkstiff #
        
        Runge-Kutta nonlinear-PDE solver for equations of the form 
        <code>u<sub>t</sub> = Lu + NL(u)</code> with adaptive-step
        Runge-Kutta methods using either integrating factor (IF) or exponential time-differencing (ETD).
        Some examples of non-linear PDES that can be numerically solved using these methods are:
        - Nonlinear Schrodinger equation (NLS)
        - Kuramoto-Sivashinsky (KS)
        - Korteweg-de Vries (KdV) 
        - Burgers
        - Allen-Cahn
        - Sine-Gordon
        
        The adaptive step solver
        options provided in this package are
        1. ETD35  (5<sup>th</sup> order ETD with 3<sup>rd</sup> orderembedding)
        2. ETD34 (4<sup>th</sup> order ETD with 3<sup>rd</sup> order embedding)
        3. IF34 (4<sup>th</sup> order IF with 3<sup>rd</sup> order embedding)
        4. IF45DP (5<sup>th</sup> order IF with 4<sup>th</sup> order embedding) 
        
        In general, one should
        prefer ETD35 as it often has the best speed and stability for diagonal systems or diagonalized
        non-diagonal systems. Because the RK coefficients can be costly
        to compute IF34 can also be a good option in certain cases. 
        A detailed discussion of these solvers is provided in the journal article  <a href = https://www.sciencedirect.com/science/article/pii/S0021999114006743> Exponential time-differencing with embedded Rungeâ€“Kutta adaptive step control </a>.
        
        # Dependencies
        
        Package requires
        <ul>
        <li> numpy </li>
        <li> scipy </li>
        </ul>
        Tested with versions
        <ul>
        <li> numpy = 1.19.2 </li>
        <li> scipy = 1.6.0 </li>
        </ul>
        
        
        # Usage #
        
        Each of the solvers is a python class (UPPERCASE) stored in a module of the same name (lowercase). Initializing each class requires two arguments, a linear operator `L` in the form of a numpy array, and a nonlinear function `NL(u)`. The solvers can then be proagated either by using the solver.step function (user steps through time) or using the solver.evolve function (stepping handled internally). For example 
        
        ```python
        from rkstiff import etd35
        L = # some linear operator 
        def NL(u): #  nonlinear function defined here 
        solver = etd35.ETD35(linop=L,NLfunc=NL)
        u0 = # initial field to be propagated 
        t0 =  # initial time 
        tf = # final time
        uf = solver.evolve(u0,t0=t0,tf=tf)
        ```
        
        By default, when using the function evolve, the field is stored at each step in a python list: u0,u1,...,uf are stored in solver.u. The corresponding times t0,t1,...,tf are stored in solver.t.
        
        # Example #
        
        Consider the Kuramoto-Sivashinsky (KS) equation: 
        <br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
         u<sub>t</sub> = -u<sub>xx</sub> - u<sub>xxxx</sub> - uu<sub>x</sub>. 
         
         Converting to spectral space using a Fourier transform (F) we have 
        <br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        v<sub>t</sub> = k<sub>x</sub><sup>2</sup>(1- k<sub>x</sub><sup>2</sup>)v - F \{ F<sup>-1</sup> \{v\} F<sup>-1</sup>\{ i k<sub>x</sub> v\} \} 
        <br>
        where v = F{u}. We can then plug L = k<sub>x</sub><sup>2</sup>(1- k<sub>x</sub><sup>2</sup>), and NL(u) =  - F \{ F<sup>-1</sup> \{v\} F<sup>-1</sup>\{ i k<sub>x</sub> v\} \} into an rkstiff solver and propagate the field u in spectral space, converting back to real space when desired. For exampe, the python code may look something like this
        ```python
        import numpy as np
        from rkstiff import grids
        from rkstiff import if34
        
        # uniform grid spacing, real-valued u -> construct_x_kx_rfft
        N = 8192
        a,b = 0,32*np.pi
        x,kx = grids.construct_x_kx_rfft(N,a,b) 
        
        L = kx**2*(1-kx**2)
        def NL(uFFT):
            u = np.fft.irfft(uFFT)
            ux = np.fft.irfft(1j*kx*uFFT)
            return -np.fft.rfft(u*ux)
        
        u0 = np.cos(x/16)*(1.+np.sin(x/16))
        u0FFT = np.fft.rfft(u0)
        solver = if34.IF34(linop=L,NLfunc=NL)
        ufFFT = solver.evolve(u0FFT,t0=0,tf=50,store_freq=20) # store every 20th step in solver.u and solver.t
        U = []
        for uFFT in solver.u:
            U.append(np.fft.irfft(uFFT))
        U = np.array(U)
        t = np.array(solver.t)
        ```
        
        The grid module in rkstiff has several useful helper functions for setting up spatial and spectral grids. Here we used it to construct grids for a real-valued `u` utilizing the real-valued numpy Fourier transform (rfft). The results of the KS 'chaotic' propagation are shown below. 
        <br>
        
        <img width="300" src="https://raw.githubusercontent.com/whalenpt/rkstiff/master/images/KSfig.png">
        
        # Installation #
        
        From the github source
        ```bash
        git clone https://github.com/whalenpt/rkstiff.git
        cd rkstiff
        python3 -m pip install numpy scipy
        python3 -m pip install .
        ```
        
        PyPI install with a virtualenv (see the <a href = https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/> Python Packaging Authority </a> guide)
        ```bash
        python3 -m venv env
        source env/bin/activate
        python3 -m pip install rkstiff
        ```
        
        For use with Anaconda (see the <a href = https://conda.io/projects/conda/en/latest/user-guide/getting-started.html> Getting started with conda </a> and  <a href = https://conda.io/projects/conda-build/en/latest/user-guide/tutorials/build-pkgs-skeleton.html> Building conda packages with conda skeleton </a> guides), from the terminal
        ```bash
        conda create --name rkstiff-env conda-build
        conda activate rkstiff-env
        conda skeleton pypi rkstiff
        conda-build rkstiff
        conda install --use-local [long_path_to_rkstiff_pkgversion_pyversion.tar.bz2]
        ```
        
        The demos require installation of the python `matplotlib` and `jupyter` packages in addition to `numpy` and `scipy`. The tests require installation of the python package `pytest`. 
        
        
        # License #
        This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
        
        # Contact #
        Patrick Whalen - whalenpt@gmail.com
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.6.0
Description-Content-Type: text/markdown
Provides-Extra: dev
