Metadata-Version: 2.1
Name: rkstiff
Version: 0.0.1
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 github download the rkstiff package.
        Once downloaded, one can install the package such that the modules can be imported outside the top level rkstiff folder. From the terminal the commands required are (assumes pip previously installed)
        ```bash
        git clone https://github.com/whalenpt/rkstiff.git
        cd rkstiff
        python3 -m pip install numpy scipy
        python3 -m pip install .
        ```
        
        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> guide), from the terminal
        ```bash
        git clone https://github.com/whalenpt/rkstiff.git
        cd rkstiff
        conda create --name rkstiff-env numpy scipy pip
        conda activate rkstiff-env
        pip install .
        ```
        
        For use with a virtualenv the install looks like (see the <a href = https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/> Python Packaging Authority </a> guide)
        ```bash
        git clone https://github.com/whalenpt/rkstiff.git
        cd rkstiff
        python3 -m venv env
        source env/bin/activate
        python3 -m pip install numpy scipy wheel
        python3 -m pip install .
        ```
        The demos require installation of the python `matplotlib` and `jupyter` packages in addition to `numpy` and `scipy`.
        
        
        # 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
