# Flow driven by an oscillating solid cylinder and bounded by a stationary outer hollow cylinder (full $\eta$ domain)

\begin{equation}\label{p1introhpa}  \Psi _{\eta \eta \tau }  = \frac{1}{{R_s }}\Psi_{\eta \eta \eta \eta }  + \Psi_{\eta \eta \eta } \Psi _\theta   - \Psi_{\eta \eta \theta } \Psi_\eta+\epsilon\Psi_{\eta\eta\theta\theta}, \\
\quad \Psi\Bigr\rvert_{\eta= \pm1} = 0,\quad \Psi_{\eta}\Bigr\rvert_{\eta= \pm1} = - sin\theta, \quad \beta_1\Psi\Bigr\rvert_{\theta= 0}+\beta_2\Psi_{\theta}\Bigr\rvert_{\theta= 0}=0 \quad \Psi\Bigr\rvert_{\theta= \pi}=0 \\
-1 \le \eta \le1, \quad 0 \le \theta \le \pi
\end{equation}

## Calculating $\Psi(\theta,\eta,t)$ the symmetric time dependent solution
The governing equation is solved using:

* Full $\eta$-domain $-1 \le \eta \le 1$
* time marching with explicit nonlinear terms and Crank-Nicolson (CN) is used when $\alpha = 0.5$
* upwinding for the terms $\Psi _{\eta \eta \theta }$ and $\Psi _{\theta }$ in the $\theta$- direction using 1st order accuracy until convergence is achieved  and then 2nd order accuracy for refinement.
* an implicit-explit cancelling damping term, $\lambda\Psi_{\eta\eta\eta\eta}$, to promote numerical stability
* Richardson extrapolation result to be included, $\Psi^{j+1}=2\Psi^{j+1}_{\mathrm{two\ steps\ of\ } \Delta t/2}-\Psi^{j+1}_{\mathrm{one\ step\ of\ }\Delta t}$, to reduce forward Euler time stepping errors to $\mathcal{O}(\Delta t^2)$.

One other aspect that could be investigated is "A general method to remove the stiffness of PDEs" using Jens Eggers method.
        On the RHS we shall add and simultanously subtract $\lambda\Psi_{\eta\eta\eta\eta}$ but at different time steps i.e on the RHS we shall have $-\lambda\Psi_{\eta\eta\eta\eta}^{j}+\lambda\Psi_{\eta\eta\eta\eta}^{j+1}$.

## Summary of results

* The numerical solution found in this notebook is calculated via time marching and only numerically stable for the tested range $0 < R_s \lesssim 350$ with a shock like discontinuity in the $\theta$-direction developing at $R_s \approx 50$
* Increasing $R_s$ above 50 requires a very small timestep ($\Delta t = 2 \times 10^{-4}$)

## Small $R_s$ series solution
The asymptotic small $R_s$ approximation for $\Psi(\theta,\eta)$ is accurate for $0 < R_s < 20$ when 5 terms are used. The approximation accuracy reduces when more terms are included; it is found that 3 terms of the small $R_s$ approximation is accurate for $0 < R_s < 40$. Hence the small $R_s$ asymptotic solution is not convergent; this demonstrated within another notebook ```SmallRSolution.ipynb``` where the first six terms of the series solution are derived using ```SymPy```.

```julia
using DifferentialEquations
using Plots
using BenchmarkTools
using DelimitedFiles
using LaTeXStrings
using SparseArrays
using LinearAlgebra
using StaticArrays
using Crayons.Box
using Printf
using Dates
```

The matrix pointer $\Psi$_j is used to refer to the streamfunction solution at the current time step and $\Psi$_jnext is the pointer to $\Psi$ at the next time step.

```julia
pyplot()

"""The asymmetric asymptotic solution for the streamfunction for small \$R_s\$ (leading order, 1st term only)"""
function Ψ_asym(θ::Float64, η::Float64 ,r::Float64)
    δ=1.96612
    return( sin(θ)*(-2.0*cos(0.5*pi*η)/pi + (0.5*(1+η)sin(0.5*pi*η)+ cos(0.5*pi*η)/pi)*δ*r^(-0.5) ) )
end

"""The symmetric (odd in η) asymptotic solution for the streamfunction for small \$R_s\$ with 5 terms"""
function Ψ_smallr(θ::Float64, η::Float64 ,r::Float64, ϵ::Float64, number_of_terms::Int)
    terms = [
        -η*(η^2-1)*sin(θ)/2.0,

        r*η*(η - 1)^2*(η + 1)^2*(η^2*cos(θ) - 7*ϵ + 2*cos(θ))*sin(θ)/280,

        r^2.0*η*(η - 1)^2*(η + 1)^2*(252*η^6*sin(θ)^2 + 168*η^6 + 4620*η^4*ϵ*cos(θ) + 1659*η^4*sin(θ)^2 - 1204*η^4 - 9240*η^2*ϵ^2 + 7392*η^2*ϵ*cos(θ) - 498*η^2*sin(θ)^2 - 200*η^2 + 20328*ϵ^2 - 23100*ϵ*cos(θ) - 1269*sin(θ)^2 + 804)*sin(θ)/15523200,

        r^3.0*η*(η - 1)^2*(η + 1)^2*(31584*η^10*sin(2*θ) + 6552*η^10*sin(4*θ) + 1705200*η^8*ϵ*sin(θ) - 317520*η^8*ϵ*sin(3*θ) -
            385182*η^8*sin(2*θ) + 72639*η^8*sin(4*θ) + 4127760*η^6*ϵ^2*sin(2*θ) - 1000188*η^6*ϵ*sin(θ) -
            2446668*η^6*ϵ*sin(3*θ) + 515004*η^6*sin(2*θ) + 56826*η^6*sin(4*θ) - 5605600*η^4*ϵ^3*sin(θ) +
            4892160*η^4*ϵ^2*sin(2*θ) - 8009876*η^4*ϵ*sin(θ) + 5934684*η^4*ϵ*sin(3*θ) + 183960*η^4*sin(2*θ) -
            304332*η^4*sin(4*θ) + 29149120*η^2*ϵ^3*sin(θ) - 66127152*η^2*ϵ^2*sin(2*θ) + 8115548*η^2*ϵ*sin(θ) +
            2568300*η^2*ϵ*sin(3*θ) - 219468*η^2*sin(2*θ) - 69258*η^2*sin(4*θ) - 45069024*ϵ^3*sin(θ) + 96943392*ϵ^2*sin(2*θ) + 931140*ϵ*sin(θ) - 3255084*ϵ*sin(3*θ) - 201930*sin(2*θ) - 44667*sin(4*θ))/678053376000,

        r^4.0*η*(η - 1)^2*(η + 1)^2*(-166486320*η^14*sin(θ)^5 - 192875760*η^14*sin(θ)^3 + 729331680*η^14*sin(θ) -
            6398371980*η^12*ϵ*sin(θ)^3*cos(θ) + 1581620040*η^12*ϵ*sin(θ)*cos(θ)^3 + 2874290265*η^12*ϵ*sin(θ)*cos(3*θ) +
            7805792610*η^12*ϵ*sin(2*θ) - 3396888495*η^12*ϵ*sin(3*θ)*cos(θ) - 3116015595*η^12*sin(θ)^5 +
            5879897100*η^12*sin(θ)^3 - 5597795280*η^12*sin(θ) + 14039182080*η^10*ϵ^2*sin(θ)^3 +
            59708307120*η^10*ϵ^2*sin(θ) - 10153337040*η^10*ϵ^2*sin(3*θ) - 54713730456*η^10*ϵ*sin(θ)^3*cos(θ) +
            2060161488*η^10*ϵ*sin(θ)*cos(θ)^3 + 24109198344*η^10*ϵ*sin(θ)*cos(3*θ) - 17172620850*η^10*ϵ*sin(2*θ) -
            19651536828*η^10*ϵ*sin(3*θ)*cos(θ) - 6247302138*η^10*sin(θ)^5 - 8654843736*η^10*sin(θ)^3 +
            18025332864*η^10*sin(θ) + 81895228800*η^8*ϵ^3*sin(2*θ) + 103100243400*η^8*ϵ^2*sin(θ)^3 -
            171932974290*η^8*ϵ^2*sin(θ) - 98289943290*η^8*ϵ^2*sin(3*θ) + 34542360468*η^8*ϵ*sin(θ)^3*cos(θ) +
            7051297176*η^8*ϵ*sin(θ)*cos(θ)^3 - 111609561987*η^8*ϵ*sin(θ)*cos(3*θ) + 18016888890*η^8*ϵ*sin(2*θ) +
            105911490069*η^8*ϵ*sin(3*θ)*cos(θ) + 20329323399*η^8*sin(θ)^5 + 16546314708*η^8*sin(θ)^3 -
            32057244912*η^8*sin(θ) - 38022784800*η^6*ϵ^4*sin(θ) + 61128938640*η^6*ϵ^3*sin(2*θ) -
            822395230272*η^6*ϵ^2*sin(θ)^3 - 107512557768*η^6*ϵ^2*sin(θ) + 455207943960*η^6*ϵ^2*sin(3*θ) +
            394629315696*η^6*ϵ*sin(θ)^3*cos(θ) - 88337719008*η^6*ϵ*sin(θ)*cos(θ)^3 + 58822993152*η^6*ϵ*sin(θ)*cos(3*θ) -
            31163444928*η^6*ϵ*sin(2*θ) - 111015717120*η^6*ϵ*sin(3*θ)*cos(θ) + 35946710100*η^6*sin(θ)^5 -
            64380538656*η^6*sin(θ)^3 + 27001794624*η^6*sin(θ) + 342205063200*η^4*ϵ^4*sin(θ) -
            2988966934800*η^4*ϵ^3*sin(2*θ) + 1702677016656*η^4*ϵ^2*sin(θ)^3 + 806106018564*η^4*ϵ^2*sin(θ) -
            86961451500*η^4*ϵ^2*sin(3*θ) - 263906374116*η^4*ϵ*sin(θ)^3*cos(θ) + 81734380728*η^4*ϵ*sin(θ)*cos(θ)^3 +
            95749015131*η^4*ϵ*sin(θ)*cos(3*θ) - 31243947966*η^4*ϵ*sin(2*θ) - 32684360709*η^4*ϵ*sin(3*θ)*cos(θ) -
            25519339629*η^4*sin(θ)^5 + 15203078100*η^4*sin(θ)^3 + 3703999600*η^4*sin(θ) - 1213470017760*η^2*ϵ^4*sin(θ) +
            10913232840048*η^2*ϵ^3*sin(2*θ) - 456130160640*η^2*ϵ^2*sin(θ)^3 - 1092696640728*η^2*ϵ^2*sin(θ) -
            1021968291960*η^2*ϵ^2*sin(3*θ) - 284869800600*η^2*ϵ*sin(θ)^3*cos(θ) + 85871943696*η^2*ϵ*sin(θ)*cos(θ)^3 -
            77948956008*η^2*ϵ*sin(θ)*cos(3*θ) + 26165014722*η^2*ϵ*sin(2*θ) + 62736207996*η^2*ϵ*sin(3*θ)*cos(θ) -
            32293847178*η^2*sin(θ)^5 + 37628191080*η^2*sin(θ)^3 - 6342526624*η^2*sin(θ) + 1681041634272*ϵ^4*sin(θ) -
            13985406998640*ϵ^3*sin(2*θ) + 3543939025704*ϵ^2*sin(θ)^3 - 2758211757378*ϵ^2*sin(θ) +
            1091197665558*ϵ^2*sin(3*θ) - 361125041508*ϵ*sin(θ)^3*cos(θ) + 90009506664*ϵ*sin(θ)*cos(θ)^3 +
            74228185647*ϵ*sin(θ)*cos(3*θ) + 135056947410*ϵ*sin(2*θ) + 49531739103*ϵ*sin(3*θ)*cos(θ) -
            51666013647*sin(θ)^5 + 66052189260*sin(θ)^3 - 16389052848*sin(θ))/505915965434880000
        ]
    if number_of_terms < 6
        return sum(terms[1:number_of_terms])
    else
        return term[1]
    end
end

"""First η-derivative of the symmetric streamfunction calculated from the small \$R_s\$ asymptotic series (3 terms)"""
function Ψ_η_smallr(θ::Float64, η::Float64 ,r::Float64)
    return(-(3.0*η^2-1)*sin(θ)/2.0 + r*(7*η^6-9*η^2+2)*sin(2*θ)/560.0 +
        r^2.0*(3*(-197 - 1112*η^2 + 6930*η^4 - 2772*η^6 - 8085*η^8 + 5236*η^10)*sin(θ) + (1269 - 6120*η^2 - 6930*η^4 + 24948*η^6 - 10395*η^8 - 2772*η^10)*sin(3*θ))/62092800.0)
end

"""Second η-derivative of the symmetric streamfunction calculated from the small \$R_s\$ asymptotic series (3 terms)"""
function  Ψ_ηη_smallr(θ::Float64, η::Float64 ,r::Float64)
    return(-3.0*η*sin(θ) + r*(42*η^5-18*η)*sin(2*θ)/560.0 +
        r^2.0*(3*( - 2224*η + 27720*η^3 - 16632*η^5 - 64680*η^7 + 52360*η^9)*sin(θ) +
            (- 12240*η - 27720*η^3 + 149688*η^5 - 83160*η^7 - 27720*η^9)*sin(3*θ))/62092800.0)
end

"""Third η-derivative of the symmetric streamfunction calculated from the small \$R_s\$ asymptotic series (3 terms)"""
function  Ψ_ηηη_smallr(θ::Float64, η::Float64 ,r::Float64)
    return(-3.0*sin(θ) + r*(210*η^4-18)*sin(2*θ)/560.0 +
        r^2.0*(3*( - 2224 + 83160*η^2 - 83160*η^4 - 452760*η^6 + 471240*η^8)*sin(θ) + (- 12240 - 83160*η^2 + 748440*η^4 - 582120*η^6 - 249480*η^8)*sin(3*θ))/62092800.0)
end

"""Fourth η-derivative of the symmetric streamfunction calculated from the small \$R_s\$ asymptotic series (3 terms)"""
function  Ψ_ηηηη_smallr(θ::Float64, η::Float64 ,r::Float64)
    return(3*r*η*(3*r*η^6*sin(θ)^2/70 + r*η^6/35 + 3*r*η^4*sin(θ)^2/40 - r*η^4/10 - 9*r*η^2*sin(θ)^2/140 + 3*r*η^2/70 + r*sin(θ)^2/280 + η^2*cos(θ))*sin(θ))
end

"""1st θ-derivative of the symmetric streamfunction calculated from the small \$R_s\$ asymptotic series (3 terms)"""
function  Ψ_θ_smallr(θ::Float64, η::Float64 ,r::Float64)
return (-η*(η - 1)*(η + 1)*(756*r^2*η^8*cos(θ)^3 - 924*r^2*η^8*cos(θ) + 4221*r^2*η^6*cos(θ)^3 - 2849*r^2*η^6*cos(θ) - 6471*r^2*η^4*cos(θ)^3 + 5467*r^2*η^4*cos(θ) - 2313*r^2*η^2*cos(θ)^3 + 1309*r^2*η^2*cos(θ) + 3807*r^2*cos(θ)^3 - 3003*r^2*cos(θ) - 55440*r*η^4*cos(2*θ) - 55440*r*η^2*cos(2*θ) + 110880*r*cos(2*θ) + 7761600*cos(θ))/15523200)
end

"""ηηθ-derivative of the symmetric streamfunction calculated from the small \$R_s\$ asymptotic series (3 terms)"""
function  Ψ_ηηθ_smallr(θ::Float64, η::Float64 ,r::Float64)
return (η*(3465*r^2*η^8*sin(θ)^2*cos(θ) + 770*r^2*η^8*cos(θ) + 10395*r^2*η^6*sin(θ)^2*cos(θ) - 4620*r^2*η^6*cos(θ) - 18711*r^2*η^4*sin(θ)^2*cos(θ) + 4158*r^2*η^4*cos(θ) + 3465*r^2*η^2*sin(θ)^2*cos(θ) + 1530*r^2*sin(θ)^2*cos(θ) - 452*r^2*cos(θ) + 97020*r*η^4*cos(2*θ) - 41580*r*cos(2*θ) - 1940400*cos(θ))/646800)
end

"""The symmetric (odd in η) asymptotic solution for the streamfunction for large \$R_s\$ with 1 term"""
function Ψ_bigr(θ::Float64, η::Float64)
    return(sin(pi*η)*sin(θ)/pi)
end

"""First η-derivative of the symmetric streamfunction calculated from the large \$R_s\$ asymptotic solution with 1 term"""
function Ψ_η_bigr(θ::Float64, η::Float64)
    return(cos(pi*η)*sin(θ))
end

"""Second η-derivative of the symmetric streamfunction calculated from the large \$R_s\$ asymptotic solution with 1 term"""
function  Ψ_ηη_bigr(θ::Float64, η::Float64)
    return(-sin(pi*η)*sin(θ)*pi)
end

"""Third η-derivative of the symmetric streamfunction calculated from the large \$R_s\$ asymptotic solution with 1 term"""
function  Ψ_ηηη_bigr(θ::Float64, η::Float64)
     return(-cos(pi*η)*sin(θ)*pi^2)
end

"""Σ |Ψ[n,m]| calculated for  1 ≤ m ≤ m_max  (with  1 ≤ n ≤ N +1 i.e. -1 ≤ η ≤ 1) """
function ψ_norm_η(ψ::Matrix{Float64}, m_max::Int64)
    norm_sum = 0.0
    for m = 1:m_max
        norm_sum += sum(abs.(ψ[:,m]))
    end
    return norm_sum
end

"""Σ |Ψ[n,m]| calculated for n_step-ϵ ≤ n ≤ n_step-ϵ (with 1 ≤ m ≤ M+1 i.e. 0 ≤ θ ≤ π)"""
function ψ_norm_θ(ψ::Matrix{Float64}, n_step::Int64, ϵ::Int64)
    norm_sum = 0.0
    for n = n_step-ϵ:n_step+ϵ
        norm_sum += sum(abs.(ψ[n,:]))
    end
    return norm_sum
end

""" Calculates ψ_ηηθθ using central/backward/forward differences"""
function ψ_ηηθθ(ψ::Matrix{Float64},n::Int64, m::Int64,  meshsize::SVector{2, Int64}, ψ_ηηη::Float64)
    (N, M) = meshsize
    derivative = 0.0;
    #if m > 2 && ψ_ηηη >= 0.0 #Backward difference
    #    derivative = (ψ[n-1,m-2]-2*ψ[n,m-2] + ψ[n+1,m-2]) -2*(ψ[n-1,m-1]-2*ψ[n,m-1] + ψ[n+1,m-1]) + (ψ[n-1,m]-2*ψ[n,m] + ψ[n+1,m])
    #elseif  m  < M && ψ_ηηη < 0.0 #Forward difference
    #    derivative = (ψ[n-1,m]-2*ψ[n,m] + ψ[n+1,m]) -2*(ψ[n-1,m+1]-2*ψ[n,m+1]+ ψ[n+1,m+1]) + (ψ[n-1,m+2]-2*ψ[n,m+2] + ψ[n+1,m+2])
    #elseif m == 2 #Forward difference
    #    derivative = (ψ[n-1,m]-2*ψ[n,m] + ψ[n+1,m]) -2*(ψ[n-1,m+1]-2*ψ[n,m+1]+ ψ[n+1,m+1]) + (ψ[n-1,m+2]-2*ψ[n,m+2] + ψ[n+1,m+2])
    #elseif m == M #Backward difference
    #    derivative = (ψ[n-1,m-2]-2*ψ[n,m-2] + ψ[n+1,m-2]) -2*(ψ[n-1,m-1]-2*ψ[n,m-1] + ψ[n+1,m-1]) + (ψ[n-1,m]-2*ψ[n,m] + ψ[n+1,m])
    #else
    #    println("Error in ψ_ηηθθ")
    #end

    # Central difference formula used
    if m > 1
    derivative = (ψ[n-1,m-1]-2*ψ[n,m-1] + ψ[n+1,m-1]) -2*(ψ[n-1,m]-2*ψ[n,m] + ψ[n+1,m]) + (ψ[n-1,m+1]-2*ψ[n,m+1] + ψ[n+1,m+1])
    else
    derivative = (ψ[n-1,m]-2*ψ[n,m] + ψ[n+1,m]) -2*(ψ[n-1,m+1]-2*ψ[n,m+1] + ψ[n+1,m+1]) + (ψ[n-1,m+2]-2*ψ[n,m+2] + ψ[n+1,m+2])
    end
    return derivative
end

"""This function selects the correct tolerance value for the convergence """
function convergence_tol(metric::String, order_str::String, switch_to_high_order::Bool)
    conv_tol::Float64  = 5*10^-5;
    if metric == "eta"
        if order_str == "1stOrder"
            if switch_to_high_order == true
                conv_tol =  2*10^-5
            else
                conv_tol =  5*10^-7
            end
        else #If not first order then higher convergence used
            conv_tol = 5*10^-7
        end
    elseif metric == "theta"
       if order_str == "1stOrder"
            if switch_to_high_order == true
                conv_tol =  5*10^-6
            else
                conv_tol =  5*10^-7
            end
        else #If not first order then higher convergence used
            conv_tol = 5*10^-7
        end
    end
    return conv_tol
end

"""Upwinding θ-derivative is calculated for the term ψ_θ in the core region of the η-mesh 2 < n < N-1"""
function ψ_θ_core_wind(ψ::Matrix{Float64}, n::Int64, m::Int64,  meshsize::SVector{2, Int64}, ψ_ηηη::Float64, orders::SVector{2, String})
    #If ψ_ηηη > 0 then upwind with forward difference
    #This function should only be called for 2<n<N-1
    derivative = 0.0
    M = meshsize[2]
    psiθ_order = orders[1]
    if (ψ_ηηη < 0.0 ) #Forward difference
        if psiθ_order=="2ndOrder" && m < M #Second order
            derivative =  -1.5*ψ[n,m] + 2.0*ψ[n,m+1]-0.5*ψ[n,m+2]
        elseif m < M+1 #First order
            derivative = -ψ[n,m] + ψ[n,m+1]
        elseif m == M+1 #Backward difference is the only option on boundary
            derivative = -ψ[n,m-1] + ψ[n,m]
        else
            println("Problem in ψ_θ_core_wind")
        end
    else  #Backward difference is chosen when possible else forward difference is used
        if psiθ_order=="2ndOrder" && m > 2 #Second order
            derivative =  0.5*ψ[n,m-2]- 2.0*ψ[n,m-1] + 1.5*ψ[n,m]
        elseif m > 1
            derivative = -ψ[n,m-1] + ψ[n,m]
        elseif m == 1 #Here we can apply the derivative boundary condition at \theta = 0
            if psiθ_order=="2ndOrder"
                derivative =  -1.5*ψ[n,m] + 2.0*ψ[n,m+1]-0.5*ψ[n,m+2]
            else
                derivative = -ψ[n,m] + ψ[n,m+1]
            end
        end

    end
    return derivative
end

"""Upwinding θ-derivative is calculated for the term ψ_θ on the boundary of n=2 and n=N i.e. η= 0+Δη and η=1-Δη"""
function ψ_θ_boundary_wind(ψ::Matrix{Float64}, n::Int64, m::Int64,  meshsize::SVector{2, Int64}, ψ_ηηη::Float64, orders::SVector{2, String})
    #If ψ_ηηη < 0 then upwind with forward difference (not sure why this works)
    #This function should only be called for n = 2 or n = N
    derivative = 0.0
    M = meshsize[2]
    psiθ_order = orders[1]
    if (ψ_ηηη < 0.0 ) #forward difference
        if psiθ_order=="2ndOrder" && m < M #Second order
            derivative =  -1.5*ψ[n,m] + 2.0*ψ[n,m+1]-0.5*ψ[n,m+2]
        elseif m < M+1 #First order forward difference
            derivative = -ψ[n,m] + ψ[n,m+1]
        elseif m == M+1 #Backward difference is the only option on boundary
            derivative = -ψ[n,m-1] + ψ[n,m]
        else
            println("Problem in ψ_θ_boundary_wind")
        end
    else   #Backward difference is chosen when possible else forward difference is used
        if psiθ_order=="2ndOrder" && m > 2 #Second order
            derivative =  0.5*ψ[n,m-2]- 2.0*ψ[n,m-1] + 1.5*ψ[n,m]
        elseif m > 1
            derivative = -ψ[n,m-1] + ψ[n,m]
        elseif m == 1 #Forward difference is the only option
            if psiθ_order=="2ndOrder"
                derivative =  -1.5*ψ[n,m] + 2.0*ψ[n,m+1]-0.5*ψ[n,m+2]
            else
                derivative = -ψ[n,m] + ψ[n,m+1]
            end

        end
    end
    return derivative
end

"""Upwinding θ-derivative is calculated for the term ψ_ηηθ in the core region of the η-mesh 2 < n < N-1"""
function ψ_ηηθ_core_wind(ψ::Matrix{Float64}, n::Int64, m::Int64,  meshsize::SVector{2, Int64}, ψ_η::Float64, orders::SVector{2, String})
    #If ψ_η < 0 then upwind with forward difference, higher order finite differences are less dissipative
    #This function should only be called for 2<n<N-1
    derivative = 0.0
    M = meshsize[2]
    psiηηθ_order = orders[2]

    if ψ_η < 0.0    #Forward difference, the appropriate order FD is now chosen
        if psiηηθ_order=="2ndOrder" && m < M  #Second order if m < M
     derivative = -1.5*(-ψ[n-2,m  ]/12 +  4*ψ[n-1,m  ]/3  -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)+
                    +2*(-ψ[n-2,m+1]/12 +  4*ψ[n-1,m+1]/3  -5*ψ[n,m+1]/2 + 4*ψ[n+1,m+1]/3 -ψ[n+2,m+1]/12)+
                  -0.5*(-ψ[n-2,m+2]/12 +  4*ψ[n-1,m+2]/3  -5*ψ[n,m+2]/2 + 4*ψ[n+1,m+2]/3 -ψ[n+2,m+2]/12)

        elseif m < M+1 #First order forward difference provided m < M + 1
            derivative = -( -ψ[n-2,m  ]/12 +  4*ψ[n-1,m  ]/3  -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)+
                          ( -ψ[n-2,m+1]/12 +  4*ψ[n-1,m+1]/3  -5*ψ[n,m+1]/2 + 4*ψ[n+1,m+1]/3 -ψ[n+2,m+1]/12)
        elseif m == M+1 #Backward difference is the only option on boundary
            derivative = -(  -ψ[n-2,m-1]/12 +  4*ψ[n-1,m-1]/3 -5*ψ[n,m-1]/2 + 4*ψ[n+1,m-1]/3 -ψ[n+2,m-1]/12)+
                           ( -ψ[n-2,m  ]/12 +  4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)
        else
            println("Problem in ψ_ηηθ_core_wind")
        end

    else  #Backward difference is chosen when possible else forward difference is used
        if psiηηθ_order=="2ndOrder" && m > 2   #Second order if m > 2
    derivative =  0.5*(-ψ[n-2,m-2]/12 +  4*ψ[n-1,m-2]/3 -5*ψ[n,m-2]/2 + 4*ψ[n+1,m-2]/3 -ψ[n+2,m-2]/12)+
                   -2*(-ψ[n-2,m-1]/12 +  4*ψ[n-1,m-1]/3 -5*ψ[n,m-1]/2 + 4*ψ[n+1,m-1]/3 -ψ[n+2,m-1]/12)+
                 +1.5*(-ψ[n-2,m  ]/12 +  4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)
        elseif m > 1
      derivative = -(  -ψ[n-2,m-1]/12 +  4*ψ[n-1,m-1]/3 -5*ψ[n,m-1]/2 + 4*ψ[n+1,m-1]/3 -ψ[n+2,m-1]/12)+
                     ( -ψ[n-2,m  ]/12 +  4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)
        elseif m == 1 #Forward difference is the only option
            if psiθ_order=="2ndOrder"
            derivative = -1.5*(-ψ[n-2,m  ]/12 +  4*ψ[n-1,m  ]/3  -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)+
                           +2*(-ψ[n-2,m+1]/12 +  4*ψ[n-1,m+1]/3  -5*ψ[n,m+1]/2 + 4*ψ[n+1,m+1]/3 -ψ[n+2,m+1]/12)+
                        -0.5*(-ψ[n-2,m+2]/12 +  4*ψ[n-1,m+2]/3  -5*ψ[n,m+2]/2 + 4*ψ[n+1,m+2]/3 -ψ[n+2,m+2]/12)
            else
                derivative = -( -ψ[n-2,m  ]/12 +  4*ψ[n-1,m  ]/3  -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)+
                              ( -ψ[n-2,m+1]/12 +  4*ψ[n-1,m+1]/3  -5*ψ[n,m+1]/2 + 4*ψ[n+1,m+1]/3 -ψ[n+2,m+1]/12)
            end
        end
    end
    return derivative
end

"""Upwinding θ-derivative is calculated for the term ψ_ηηθ on the boundary of n=2 and n=N i.e. η=0+Δη and η=1-Δη"""
function ψ_ηηθ_boundary_wind(ψ::Matrix{Float64}, n::Int64, m::Int64, delta_sizes::SVector{2, Float64}, meshsize::SVector{2, Int64}, ψ_η::Float64, orders::SVector{2, String})
    #If ψ_η < 0 then upwind with forward difference
    #This function should only be called for n= 2 and n = N
    psiηηθ_order =orders[2]
    (N, M) = meshsize
    (Δθ, Δη) = delta_sizes
    derivative = 0.0
    bc=2*Δη*sin(Δθ*(m-1))
    bcp1=2*Δη*sin(Δθ*m)
    bcp2=2*Δη*sin(Δθ*(m+1))
    bcm1=2*Δη*sin(Δθ*(m-2))
    bcm2=2*Δη*sin(Δθ*(m-3))

    if n==2
        if ψ_η < 0.0    #Forward difference
            if psiηηθ_order=="2ndOrder" && m < M #Second order forward difference
            derivative =  -1.5*(-(ψ[2,m ]+bc)/12 +  4*ψ[n-1,m  ]/3  -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)+
                            +2*(-(ψ[2,m+1]+bcp1)/12 +  4*ψ[n-1,m+1]/3  -5*ψ[n,m+1]/2 + 4*ψ[n+1,m+1]/3 -ψ[n+2,m+1]/12)+
                          -0.5*(-(ψ[2,m+2]+bcp2)/12 +  4*ψ[n-1,m+2]/3  -5*ψ[n,m+2]/2 + 4*ψ[n+1,m+2]/3 -ψ[n+2,m+2]/12)
            elseif m < M +1        #First order forward difference provided m < M + 1
            derivative= -(-(ψ[2,m ]+bc)/12 + 4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)+
                     +(-(ψ[2,m+1]+bcp1)/12 + 4*ψ[n-1,m+1]/3 -5*ψ[n,m+1]/2 + 4*ψ[n+1,m+1]/3 -ψ[n+2,m+1]/12)
            elseif m == M+1        #Backward difference is the only option on boundary
            derivative=-(-(ψ[2,m-1]+bcm1)/12 + 4*ψ[n-1,m-1]/3 -5*ψ[n,m-1]/2 + 4*ψ[n+1,m-1]/3 -ψ[n+2,m-1]/12)+
                       +(-(ψ[2,m  ]+bc  )/12 + 4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)
            else
                println("Error in ψ_ηηθ_boundary_wind n == 2")
            end

        else            #Backward difference is the default
            if psiηηθ_order=="2ndOrder" && m > 2 #Second order backward
            derivative = 0.5*(-(ψ[2,m-2]+bcm2)/12 +  4*ψ[n-1,m-2]/3 -5*ψ[n,m-2]/2 + 4*ψ[n+1,m-2]/3 -ψ[n+2,m-2]/12)+
                          -2*(-(ψ[2,m-1]+bcm1)/12 +  4*ψ[n-1,m-1]/3 -5*ψ[n,m-1]/2 + 4*ψ[n+1,m-1]/3 -ψ[n+2,m-1]/12)+
                        +1.5*(-(ψ[2,m  ]+bc  )/12 +  4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)
            elseif m > 1        #First order backward
            derivative=-(-(ψ[2,m-1]+bcm1)/12 + 4*ψ[n-1,m-1]/3 -5*ψ[n,m-1]/2 + 4*ψ[n+1,m-1]/3 -ψ[n+2,m-1]/12)+
                       +(-(ψ[2,m  ]+bc  )/12 + 4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)
            elseif m == 1 #Forward difference is the only option
                if psiθ_order=="2ndOrder"
                    derivative =  -1.5*(-(ψ[2,m ]+bc)/12 +  4*ψ[n-1,m  ]/3  -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)+
                                    +2*(-(ψ[2,m+1]+bcp1)/12 +  4*ψ[n-1,m+1]/3  -5*ψ[n,m+1]/2 + 4*ψ[n+1,m+1]/3 -ψ[n+2,m+1]/12)+
                                  -0.5*(-(ψ[2,m+2]+bcp2)/12 +  4*ψ[n-1,m+2]/3  -5*ψ[n,m+2]/2 + 4*ψ[n+1,m+2]/3 -ψ[n+2,m+2]/12)
                else #First order forward difference
                    derivative =  -(-(ψ[2,m ]+bc)/12 + 4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -ψ[n+2,m  ]/12)+
                               +(-(ψ[2,m+1]+bcp1)/12 + 4*ψ[n-1,m+1]/3 -5*ψ[n,m+1]/2 + 4*ψ[n+1,m+1]/3 -ψ[n+2,m+1]/12)
                end
            end
        end

    elseif n == N

        if ψ_η < 0.0   #Forward difference
            if psiηηθ_order=="2ndOrder" && m < M #Second order forward difference
            derivative =-1.5*(-ψ[n-2,m  ]/12 +  4*ψ[n-1,m  ]/3  -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -(ψ[N,m  ]-bc)/12)+
                          +2*(-ψ[n-2,m+1]/12 +  4*ψ[n-1,m+1]/3  -5*ψ[n,m+1]/2 + 4*ψ[n+1,m+1]/3 -(ψ[N,m+1]-bcp1)/12)+
                        -0.5*(-ψ[n-2,m+2]/12 +  4*ψ[n-1,m+2]/3  -5*ψ[n,m+2]/2 + 4*ψ[n+1,m+2]/3 -(ψ[N,m+2]-bcp2)/12)
            elseif  m < M +1    #First order forward difference provided m < M + 1
            derivative=-(-ψ[n-2,m  ]/12 + 4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -(ψ[N,m  ]-bc)/12)+
                        (-ψ[n-2,m+1]/12 + 4*ψ[n-1,m+1]/3 -5*ψ[n,m+1]/2 + 4*ψ[n+1,m+1]/3 -(ψ[N,m+1]-bcp1)/12)
            elseif m == M+1      #Backward difference is the only option on boundary
            derivative=-(-ψ[n-2,m-1]/12 + 4*ψ[n-1,m-1]/3 -5*ψ[n,m-1]/2 + 4*ψ[n+1,m-1]/3 -(ψ[N,m-1]-bcm1)/12)+
                        (-ψ[n-2,m  ]/12 + 4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -(ψ[N,m  ]-bc  )/12)
            else
                 println("Error in ψ_ηηθ_boundary_wind n == N")
            end

        else           #Backward difference
            if psiηηθ_order=="2ndOrder" && m > 2 #Second order backward
        derivative =0.5*(-ψ[n-2,m-2]/12 +  4*ψ[n-1,m-2]/3 -5*ψ[n,m-2]/2 + 4*ψ[n+1,m-2]/3 -(ψ[N,m-2]-bcm2)/12)+
                     -2*(-ψ[n-2,m-1]/12 +  4*ψ[n-1,m-1]/3 -5*ψ[n,m-1]/2 + 4*ψ[n+1,m-1]/3 -(ψ[N,m-1]-bcm1)/12)+
                   +1.5*(-ψ[n-2,m  ]/12 +  4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -(ψ[N,m  ]-bc  )/12)
            elseif m > 1   #First order backward
        derivative=-(-ψ[n-2,m-1]/12 + 4*ψ[n-1,m-1]/3 -5*ψ[n,m-1]/2 + 4*ψ[n+1,m-1]/3 -(ψ[N,m-1]-bcm1)/12)+
                    (-ψ[n-2,m  ]/12 + 4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -(ψ[N,m  ]-bc  )/12)
            elseif m == 1
                if psiθ_order=="2ndOrder"
                    derivative =  -1.5*(-ψ[n-2,m  ]/12 +  4*ψ[n-1,m  ]/3  -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -(ψ[N,m  ]-bc)/12)+
                                    +2*(-ψ[n-2,m+1]/12 +  4*ψ[n-1,m+1]/3  -5*ψ[n,m+1]/2 + 4*ψ[n+1,m+1]/3 -(ψ[N,m+1]-bcp1)/12)+
                                  -0.5*(-ψ[n-2,m+2]/12 +  4*ψ[n-1,m+2]/3  -5*ψ[n,m+2]/2 + 4*ψ[n+1,m+2]/3 -(ψ[N,m+2]-bcp2)/12)
                else #First order forward difference
                    derivative =  -(-ψ[n-2,m  ]/12 + 4*ψ[n-1,m  ]/3 -5*ψ[n,m  ]/2 + 4*ψ[n+1,m  ]/3 -(ψ[N,m  ]-bc)/12)+
                                  +(-ψ[n-2,m+1]/12 + 4*ψ[n-1,m+1]/3 -5*ψ[n,m+1]/2 + 4*ψ[n+1,m+1]/3 -(ψ[N,m+1]-bcp1)/12)
                end

            end
        end
    else
        println("Error in ψ_ηηθ_boundary_wind")
    end
    return derivative
end

"""ψ at the next time step, represented as ψ_next, is computed at the boundaries m =2, M
from ψ at the current time step, represented as ψ, with an inplace matrix inversion"""
function make_ψ_jnext_on_boundaries(ψ::Matrix{Float64}, ψ_next::Matrix{Float64}, LUA, paramtrs::SVector{9, Float64}, meshsize::SVector{2, Int64}, delta_sizes::SVector{2, Float64}, orders::SVector{2, String})
    (R, rc, rd1, rd2, rd3, d1, d2, d3, ϵ_adjusted) = paramtrs
    (Δθ, Δη) = delta_sizes
    (N, M) = meshsize

    for m in (1, 2, M) #A second order finite difference scheme is used at the first and last interior θ-profiles at m = 2 and m = M

    #At n=1 ψ[1,:] = 0 (due to the condition ψ(η=-1)=0) and we only need to calculate the interior points from n=2 to n=N

    n=2
    bc=2*Δη*sin(Δθ*(m-1))
    bcp1=2*Δη*sin(Δθ*m)
    bcm1=2*Δη*sin(Δθ*(m-2))

    rhs = @view ψ_next[2:N,m]

    ψ_ηηη = -(ψ[2,m]+bc)/2 +     ψ[n-1,m]      -ψ[n+1,m]   + ψ[n+2,m]/2
    ψ_η   =  (ψ[2,m]+bc)/12 -  2*ψ[n-1,m]/3  +2*ψ[n+1,m]/3 - ψ[n+2,m]/12
    rhs[1] = rd3*(ψ[2,m]+bc)    +    rd2*ψ[n-1,m] + rd1*ψ[n,m] + rd2*ψ[n+1,m] + rd3*ψ[n+2,m] +
        + rc*ψ_ηηη*ψ_θ_boundary_wind(ψ, n, m, meshsize, ψ_ηηη, orders) +
        - rc*ψ_ηηθ_boundary_wind(ψ, n, m, delta_sizes, meshsize, ψ_η, orders)*ψ_η+
        + ψ_ηηθθ(ψ, n, m, meshsize, ψ_ηηη)*ϵ_adjusted - d3*bc

        for n = 3:N-1
        ψ_ηηη = -ψ[n-2,m]/2 +     ψ[n-1,m]      -ψ[n+1,m]   + ψ[n+2,m]/2
        ψ_η   =  ψ[n-2,m]/12 -  2*ψ[n-1,m]/3  +2*ψ[n+1,m]/3 - ψ[n+2,m]/12
        rhs[n-1] = rd3*ψ[n-2,m]    +    rd2*ψ[n-1,m] + rd1*ψ[n,m] + rd2*ψ[n+1,m] + rd3*ψ[n+2,m] +
                + rc*ψ_ηηη*ψ_θ_core_wind(ψ, n, m, meshsize, ψ_ηηη, orders)- rc*ψ_η*ψ_ηηθ_core_wind(ψ, n, m, meshsize, ψ_η, orders)+
                + ψ_ηηθθ(ψ, n, m, meshsize, ψ_ηηη)*ϵ_adjusted
        end#End of the n loop

    #at n=N psi[N+1,:] = 0
    n=N
    ψ_ηηη = -ψ[n-2,m]/2 +     ψ[n-1,m]      -ψ[n+1,m]   + (ψ[N,m]-bc)/2
    ψ_η   =  ψ[n-2,m]/12 -  2*ψ[n-1,m]/3  +2*ψ[n+1,m]/3 - (ψ[N,m]-bc)/12
    rhs[N-1] = rd3*ψ[n-2,m]    +    rd2*ψ[n-1,m] + rd1*ψ[n,m] + rd2*ψ[n+1,m] + rd3*(ψ[N,m]-bc)+
            + rc*ψ_ηηη*ψ_θ_boundary_wind(ψ, n, m, meshsize, ψ_ηηη, orders) +
            - rc*ψ_ηηθ_boundary_wind(ψ, n, m, delta_sizes, meshsize, ψ_η, orders)*ψ_η+
            + ψ_ηηθθ(ψ, n, m, meshsize, ψ_ηηη)*ϵ_adjusted + d3*bc

    ldiv!(LUA,rhs) # For a non inplace method we could use ψ_next[2:N,m] = LUA\rhs
    end # End of the m loop
end

"""ψ at the next time step, represented as ψ_next, is computed in the core mesh region 3 ≤ m  ≤ M-1
from ψ at the current time step, represented as ψ, with an inplace matrix inversion"""
function make_ψ_jnext_in_core_region(ψ::Matrix{Float64}, ψ_next::Matrix{Float64}, LUA, paramtrs::SVector{9, Float64}, meshsize::SVector{2, Int64}, delta_sizes::SVector{2, Float64}, orders::SVector{2, String})
    (R, rc, rd1, rd2, rd3, d1, d2, d3, ϵ) = paramtrs
    (Δθ, Δη) = delta_sizes
    (N, M) = meshsize
    for m = 3:M-1

    #At n=1 ψ[1,:] = 0 (due to the condition ψ(η=-1)=0) and we only need to calculate the interior points from n=2 to n=N

    n=2
    bc=2*Δη*sin(Δθ*(m-1))
    bcp1=2*Δη*sin(Δθ*m)
    bcp2=2*Δη*sin(Δθ*(m+1))
    bcm1=2*Δη*sin(Δθ*(m-2))
    bcm2=2*Δη*sin(Δθ*(m-3))

    rhs = @view ψ_next[2:N,m]
    ψ_ηηη =    -(ψ[2,m]+bc)/2 +     ψ[n-1,m]      -ψ[n+1,m]   + ψ[n+2,m]/2
    ψ_η   =     (ψ[2,m]+bc)/12 -  2*ψ[n-1,m]/3  +2*ψ[n+1,m]/3 - ψ[n+2,m]/12
    rhs[1] = rd3*(ψ[2,m]+bc)    +    rd2*ψ[n-1,m] + rd1*ψ[n,m] + rd2*ψ[n+1,m] + rd3*ψ[n+2,m] +
            + rc*ψ_ηηη*ψ_θ_boundary_wind(ψ, n, m, meshsize, ψ_ηηη, orders) +
            - rc*ψ_ηηθ_boundary_wind(ψ, n, m, delta_sizes, meshsize, ψ_η, orders)*ψ_η +
            + ψ_ηηθθ(ψ, n, m, meshsize, ψ_ηηη)*ϵ_adjusted - d3*bc

        for n = 3:N-1
            ψ_ηηη = -ψ[n-2,m]/2 +     ψ[n-1,m]      -ψ[n+1,m]   + ψ[n+2,m]/2
            ψ_η   =  ψ[n-2,m]/12 -  2*ψ[n-1,m]/3  +2*ψ[n+1,m]/3 - ψ[n+2,m]/12
            rhs[n-1] = rd3*ψ[n-2,m]    +    rd2*ψ[n-1,m] + rd1*ψ[n,m] + rd2*ψ[n+1,m] + rd3*ψ[n+2,m]+
            + rc*ψ_ηηη*ψ_θ_core_wind(ψ,n, m, meshsize, ψ_ηηη, orders)-rc*ψ_ηηθ_core_wind(ψ,n, m, meshsize, ψ_η, orders)*ψ_η+
            + ψ_ηηθθ(ψ, n, m, meshsize, ψ_ηηη)*ϵ_adjusted
        end #End of the n loop

    #At n=N ψ[N+1,:] = 0 due to the condition ψ(η=+1)=0
    n=N
    ψ_ηηη = -ψ[n-2,m]/2 +     ψ[n-1,m]      -ψ[n+1,m]   + (ψ[N,m]-bc)/2
    ψ_η   =  ψ[n-2,m]/12 -  2*ψ[n-1,m]/3  +2*ψ[n+1,m]/3 - (ψ[N,m]-bc)/12
    rhs[N-1] = rd3*ψ[n-2,m]    +    rd2*ψ[n-1,m] + rd1*ψ[n,m] + rd2*ψ[n+1,m] + rd3*(ψ[N,m]-bc)+
            + rc*ψ_ηηη*ψ_θ_boundary_wind(ψ, n, m, meshsize, ψ_ηηη, orders)+
            - rc*ψ_ηηθ_boundary_wind(ψ, n, m, delta_sizes, meshsize, ψ_η, orders)*ψ_η +
            + ψ_ηηθθ(ψ, n, m, meshsize, ψ_ηηη)*ϵ_adjusted + d3*bc

    ldiv!(LUA,rhs) # For a non inplace method we could use ψ_next[2:N,m] = LUA\rhs
    end #End of the m loop
end

```

    make_ψ_jnext_in_core_region

```julia
const N = 256;  # Total number of intervals (steps-1) in the η direction
const M = 360;  # Total number of intervals (steps-1) in the θ direction
const J = 200000;    # Total number of time steps
ψ_current = zeros(N+1,M+1); # Initialise the matrix for the streamfunction at the current time step
ψ_next =zeros(N+1,M+1);     # Initialise the matrix for the streamfunction at the next time step
ψ_half_step = zeros(N+1,M+1)
ψ_j = ψ_current;            # Pointer assigned for the current streamfunction
ψ_jnext = ψ_next ;          # Pointer assigned for the next time step streamfunction
const Δη = 2.0/N;
const Δθ = pi/M;
const Δt = 0.0002;
const α = 0.5;             # Implicit scheme parameter coefficient of ψ_ηηηη term, set to 0.5 for Crank-Nicolson
const c = Δt/(Δη^2);
const rc    =  Δt/(Δη*Δθ);
const λ = 10.0 ;           # Implicit-explicit cancelling coeffient of ψ_ηηηη term, Jens Eggers damping method
const β = 0.0             # Boundary condition at θ = 0: βψ+ψ_θ = 0
```

    WARNING: redefinition of constant Δt. This may fail, cause incorrect answers, or produce other errors.
    WARNING: redefinition of constant c. This may fail, cause incorrect answers, or produce other errors.
    WARNING: redefinition of constant rc. This may fail, cause incorrect answers, or produce other errors.
    WARNING: redefinition of constant λ. This may fail, cause incorrect answers, or produce other errors.

```julia
const ϵ = 0.005
const ϵ_adjusted = ϵ*Δt/(Δθ)^2 #The ϵ_adjusted = ϵ*Δt*Δη^2
```

    WARNING: redefinition of constant ϵ. This may fail, cause incorrect answers, or produce other errors.
    WARNING: redefinition of constant ϵ_adjusted. This may fail, cause incorrect answers, or produce other errors.

    0.013131225400046978

```julia
#Do not re-execute this block if you intend to run the notebook a secondtime with an existing solution in RAM.
R_initial = Float64(130.0) # Initialisation Reynolds number, this is a one codeblock use convenience variable

continue_from_previous_run = false

if continue_from_previous_run # Load file with matrix N by M
    ψ_current=readdlm("R_equals_80.0/psi_solution_R_80.0_2ndOrder_RE_e_0.002.txt",Float64,); #Check that N and M lengths match
    ψ_j= ψ_current
else
    for n in 2:N
        for m in 1:M
            if R_initial < 70.0 #Translated sine wave as initial condition
                ψ_current[n,m] = Ψ_smallr(0.5*(Δθ*(m-1)-pi)+pi,-1.0+Δη*(n-1),R_initial,ϵ,3)
            else
                ψ_current[n,m] = Ψ_bigr(0.5*(Δθ*(m-1)-pi)+pi, -1.0 + Δη*(n-1))
                #ψ_current[n,m] = Ψ_smallr(Δθ*(m-1),-1.0+Δη*(n-1),R_initial,ϵ,1)
            end
        end
    end
end

```

```julia
# Initialisation of the arrays that will capture the graphical plots during timemarching
combined_plot =plot()
plot_array = Array{Plots.Plot{Plots.PyPlotBackend},1}()
plot_arraywf= Array{Plots.Plot{Plots.PyPlotBackend},1}()
ψ_1st_order = zeros(N+1,M+1) # Once the 1st Order θ-upwinding solution is steady its is stored in this matrix
eta_profile =0.6;            # This is the η-value used for plots and calculating metrics about the streamfunction
theta=range(0, stop=pi,length= M+1); # θ-domain used for generating plots
```

```julia
reynolds_values = SA{Float64}[130.0]  #Array of Reynolds numbers

const switch_to_high_order = false
const psiηηθ_order="1stOrder" #Set to either 1stOrder or 2ndOrder
const psiθ_order="1stOrder"   #Set to either 1stOrder or 2ndOrder
const θ_value_for_norm = pi/10.0        #θ-Norm will be calculated for  0 ≤ θ ≤ θ_value_for_norm and |η| ≤ 1
const η_value_for_norm = 0.6            #η-Norm will be calculated for  0 ≤ θ ≤ π and |η-η_value_for_norm| ≤ ϵ

for rey_number in reynolds_values

mkpath("R_equals_$(rey_number)") #Make a folder for the output
orders = SA{String}[psiθ_order, psiηηθ_order]
println(BLINK*BOLD*BLUE_FG("Reynolds number= $rey_number, ϵ = $ϵ ψ_ηηθ:$psiηηθ_order, ψ_θ:$psiθ_order, t_max = $(J*Δt)"))

d3::Float64 = -1.0/12.0 -   α*c/rey_number  -λ*c   #Diagonal entries for the matrix problem
d2::Float64 =  4.0/3.0 + 4*α*c/rey_number + 4*λ*c
d1::Float64 = -5.0/2.0  -6*α*c/rey_number - 6*λ*c

A =spdiagm(-2=>ones(N-3)*d3 ,-1 => ones(N-2)*d2, 0 => ones(N-1)*d1, 1 => ones(N-2)*d2,2 => ones(N-3)*d3)

A[1,1]     = d1 + d3 #Boundary condition ψ(η=-1)= 0 i.e ψ[1,:] = 0 and ψ_η(η=-1) = -sin(θ) ∴ add -2d3×Δηsin(θ) to RHS
A[end,end] = d1 + d3 #Boundary condition ψ(η=+1)= 0 i.e ψ[N+1,:] = 0 and ψ_η(η=+1) = -sin(θ) ∴ add 2d3×Δηsin(θ) to RHS
LUA = lu(A)
varinfo(r"A") #This is a handy command for tracking memory allocation to the sparse matrix

#Constructing useful coefficients for forming the righthand side vector
rd3::Float64 = -1.0/12.0 + (1-α)*c/rey_number     -λ*c
rd2::Float64 =  4.0/3.0 - 4*(1-α)*c/rey_number  + 4*λ*c
rd1::Float64 = -5.0/2.0 + 6*(1-α)*c/rey_number  - 6*λ*c

#Richardson Extrapolation
d3_re::Float64  = -1.0/12.0 + (-α/rey_number     -λ)*c/2.0   #Diagonal entries for the matrix problem
d2_re::Float64  =  4.0/3.0  + (4*α/rey_number + 4*λ)*c/2.0
d1_re::Float64  = -5.0/2.0  + (-6*α/rey_number - 6*λ)*c/2.0

A =spdiagm(-2=>ones(N-3)*d3_re ,-1 => ones(N-2)*d2_re, 0 => ones(N-1)*d1_re, 1 => ones(N-2)*d2_re,2 => ones(N-3)*d3_re)

A[1,1]     = d1_re + d3_re #Boundary condition ψ(η=-1)= 0 i.e ψ[1,:] = 0 and ψ_η(η=-1) = -sin(θ) ∴ add -2d3×Δηsin(θ) to RHS
A[end,end] = d1_re + d3_re #Boundary condition ψ(η=+1)= 0 i.e ψ[N+1,:] = 0 and ψ_η(η=+1) = -sin(θ) ∴ add 2d3×Δηsin(θ) to RHS
LUA2 = lu(A)
A = nothing

#Constructing useful coefficients for forming the righthand side vector
rd3_re::Float64  = -1.0/12.0 + (    (1-α)/rey_number    -λ)*c/2.0
rd2_re::Float64  =  4.0/3.0  + (-4*(1-α)/rey_number  + 4*λ)*c/2.0
rd1_re::Float64  = -5.0/2.0 +   (6*(1-α)/rey_number  - 6*λ)*c/2.0

paramtrs =  SA{Float64}[rey_number, rc, rd1, rd2, rd3, d1, d2, d3, ϵ_adjusted]
paramtrs_re =  SA{Float64}[rey_number, rc/2.0, rd1_re, rd2_re, rd3_re, d1_re, d2_re, d3_re, ϵ_adjusted]
meshsize = SA{Int64}[N,M]
delta_sizes= SA{Float64}[Δθ, Δη]
percent::Float64  = 0.0                    #The percentage duration of the simulation at which to print first output to screen

t1::DateTime = now()
t2::DateTime = now()

old_norm_θ::Float64 = old_norm_η::Float64 = η_norm_at_Δθ::Float64 = 0.0

@time for j =1:J

    #Iteration of stepsize \Delta t
    make_ψ_jnext_on_boundaries(ψ_j, ψ_jnext, LUA, paramtrs, meshsize, delta_sizes, orders)
    make_ψ_jnext_in_core_region(ψ_j,ψ_jnext, LUA, paramtrs, meshsize, delta_sizes, orders)

    #Iteration of stepsize \Delta t/2
    make_ψ_jnext_on_boundaries(ψ_j, ψ_half_step, LUA2, paramtrs_re, meshsize, delta_sizes, orders)
    make_ψ_jnext_in_core_region(ψ_j,ψ_half_step, LUA2, paramtrs_re, meshsize, delta_sizes, orders)

    #Iteration of stepsize \Delta t/2
    make_ψ_jnext_on_boundaries(ψ_half_step, ψ_j, LUA2, paramtrs_re, meshsize, delta_sizes, orders)
    make_ψ_jnext_in_core_region(ψ_half_step,ψ_j, LUA2, paramtrs_re, meshsize, delta_sizes, orders)

    @.  ψ_jnext = 2*ψ_j - ψ_jnext  #Richardson Extrapolation method for reducing errors to order Δt^2

    if( mod(j,2) == 1)
        ψ_j    = ψ_next
        ψ_jnext= ψ_current
    else
        ψ_j    = ψ_current
        ψ_jnext= ψ_next

    end #End of if statement

    if j > round(Int64,percent*J/100)-1 || j==1 #At regular intervals print output and check for convergence

        psi_norm_η = ψ_norm_η(ψ_j, round(Int64,θ_value_for_norm*M/pi+1))*Δη*Δθ  #Calculate simple norms of ψ
        η_norm_at_Δθ = ψ_norm_η(ψ_j, 2)*Δη*Δθ
        psi_norm_θ = ψ_norm_θ(ψ_j, round(Int64,η_value_for_norm*N+1), round(Int64,0.05*N))*Δη*Δθ

        @printf "%.1f%% t=%.1f @ θ≈Δθ Σ|Ψ|ΔηΔθ= %.5E,  @ 0≤θ≤%dΔθ Σ|Ψ|ΔηΔθ= %.7E,  @ η≈%.1f Σ|Ψ|ΔηΔθ= %.5E\n" percent j*Δt round(η_norm_at_Δθ,sigdigits=5) (θ_value_for_norm*M/pi+1) psi_norm_η η_value_for_norm psi_norm_θ
        flush(stdout)
        if (percent < 5.0)
            t2=now()+(now()-t1)*2*(100-round(Int64,percent))
            printstyled(Dates.format(now(), "HH:MM:SS")*" Estimated time to complete: "*Dates.format(t2, "HH:MM:SS"*"\n"), color=:green)
            t1 = now()
        end

        percent+=0.5
        #Wireframe plots for animation
            push!(plot_arraywf,wireframe( range(-1.0,stop = 1.0,length = round(Int,N/8)+1),range(0.0,stop = pi,length = round(Int,M/4)+1), transpose(ψ_j[1:8:end,1:4:end]), colour=:greys))
            plot!(xlabel=L"\eta", ylabel=L"\theta", zlabel=L"\Psi", size=(1000,800),camera=(-40,20), xlims = (-1, 1), ylims = (0.0, pi), zlims = (-0.22, 0.22) )
            title!(orders[1]*L"\quad θ-\mathrm{upwinding}, R_s = %$rey_number, t=%$(round(j*Δt,sigdigits=3))"*"\n"*L"N_η=%$N, M_θ=%$M, Δt=%$(Δt), ϵ = %$(ϵ)")
        if isnan(ψ_j[3,3])
           println(BOLD*RED_FG("\nΨ is no longer a number, exiting... "))
           break

        elseif abs(psi_norm_θ-old_norm_θ)< convergence_tol("theta", orders[1], switch_to_high_order) && abs(psi_norm_η-old_norm_η)< convergence_tol("eta", orders[1], switch_to_high_order) #Check for convergence

            println(BOLD*GREEN_FG("\nΨ has converged with ψ_ηηθ:$(orders[1]), ψ_θ:$(orders[2]), Reynolds number= $rey_number"))
            open("R_equals_$(rey_number)/psi_solution_R_$(rey_number)_$(orders[1])_RE_e_$(round(ϵ,sigdigits=3)).txt", "w") do io #Save the solution for the current run
               writedlm(io, ψ_current)
            end #End of the filesave do loop

            push!(plot_array, plot(theta,ψ_j[round(Int,(eta_profile+1)/Δη)+1,:], label="t=$(round(j*Δt,digits=3)) "*L"R_s =%$rey_number"*", $(orders[1])", linestyle=:solid, xlabel = L"\theta", ylabel = L"\Psi",size=(1000,500), yguidefontrotation=-90))
            vline!([θ_value_for_norm],label="θ = $(round(θ_value_for_norm,digits=3))")
            plot!([0,θ_value_for_norm],[0.15,0.15],marker =:circle, arrow=(:closed,:both, 0.5), label="ψ_norm_θ calc. range")
            plot!(combined_plot, theta,ψ_j[round(Int,(eta_profile+1)/Δη)+1,:], label="t=$(round(j*Δt,digits=3)) "*L"R_s =%$rey_number"*", $(orders[1])", linestyle=:auto, linewidth = 2, xlabel = L"\theta", ylabel = L"\Psi",size=(1000,500))

            if(switch_to_high_order && orders[1] == "1stOrder")
                    orders = SA{String}["2ndOrder","2ndOrder"]
                    println(BOLD*BLUE_FG("\nSwitching to ψ_ηηθ:$(orders[1]), ψ_θ:$(orders[2]) ... continuing iterations"))
                    ψ_1st_order .= ψ_j # Copy the converged 1stOrder solution for plotting and analysis
            elseif !switch_to_high_order && orders[1] == "1stOrder"
                    ψ_1st_order .= ψ_j # Copy the converged 1stOrder solution for plotting and analysis
                    break
            else
                    println(BOLD*GREEN_FG("exiting"))
                    break
            end
       end
        old_norm_θ = psi_norm_θ
        old_norm_η = psi_norm_η

       if percent%20 == 0      #Save graphs at regular percentage intervals
           push!(plot_array,plot(theta,ψ_j[round(Int,(eta_profile+1)/Δη)+1,:], label="t=$(round(j*Δt,sigdigits=3)) "*L"R_s =%$rey_number"*", $(orders[1])", linestyle=:solid, xlabel = L"\theta", ylabel = L"\Psi",size=(1000,500),yguidefontrotation=-90))
           vline!([θ_value_for_norm],label="θ = $(round(θ_value_for_norm,digits=3))")
           plot!([0,θ_value_for_norm],[0.15,0.15],marker =:circle, arrow=(:closed,:both, 0.5), label="ψ_norm_θ calc. range")
           plot!(combined_plot, theta,ψ_j[round(Int,(eta_profile+1)/Δη)+1,:], label="t=$(round(j*Δt,sigdigits=3)) "*L"R_s =%$rey_number"*", $(orders[1])", linestyle=:auto, linewidth = 2, xlabel = L"\theta", ylabel = L"\Psi",size=(1000,500),yguidefontrotation=-90)
       end
        close("all") #This closes all plots
    end

end #End of time loop j

    open("R_equals_$(rey_number)/psi_solution_R_$(rey_number)_RE_e_$(round(ϵ,sigdigits=3)).txt", "w") do io #Save the solution for the current run
        writedlm(io, ψ_current)
    end
end
```

    Reynolds number= 130.0, ϵ = 0.005 ψ_ηηθ:1stOrder, ψ_θ:1stOrder, t_max = 40.0
    0.0% t=0.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.11800E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.0334549E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.79732E-02
    09:29:19 Estimated time to complete: 09:29:22
    0.5% t=0.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 1.37810E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 1.9524207E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.83111E-02

    WARNING: redefinition of constant switch_to_high_order. This may fail, cause incorrect answers, or produce other errors.

    09:29:38 Estimated time to complete: 10:32:26
    1.0% t=0.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 9.56430E-05,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 1.9360409E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.85079E-02
    09:29:56 Estimated time to complete: 10:31:20
    1.5% t=0.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 9.38090E-05,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 1.9854674E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.86101E-02
    09:30:15 Estimated time to complete: 10:30:20
    2.0% t=0.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 1.00900E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.0743037E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.85608E-02
    09:30:33 Estimated time to complete: 10:30:22
    2.5% t=1.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 1.12720E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1962240E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.84694E-02
    09:30:51 Estimated time to complete: 10:31:31
    3.0% t=1.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 1.34140E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3522035E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.83827E-02
    09:31:10 Estimated time to complete: 10:31:10
    3.5% t=1.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 1.64620E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4770331E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.82804E-02
    09:31:28 Estimated time to complete: 10:30:34
    4.0% t=1.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.01470E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5631837E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.81566E-02
    09:31:47 Estimated time to complete: 10:30:19
    4.5% t=1.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.44970E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6149222E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.80015E-02
    09:32:05 Estimated time to complete: 10:31:01
    5.0% t=2.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.85560E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6350133E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.78129E-02
    5.5% t=2.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.12210E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6256212E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.76136E-02
    6.0% t=2.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.18980E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5923277E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.74405E-02
    6.5% t=2.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.09610E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5454716E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.73308E-02
    7.0% t=2.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.88840E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4961758E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.73039E-02
    7.5% t=3.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.62400E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4558645E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.73610E-02
    8.0% t=3.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.39730E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4352943E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.75024E-02
    8.5% t=3.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.39920E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4452480E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.76992E-02
    9.0% t=3.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.93620E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4926749E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.79029E-02
    9.5% t=3.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.19370E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5702233E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.80633E-02
    10.0% t=4.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.16670E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6511057E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.81452E-02
    10.5% t=4.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.46280E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.7166919E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.81230E-02
    11.0% t=4.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.48120E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.7633338E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.80126E-02
    11.5% t=4.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.52910E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.7930289E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.78492E-02
    12.0% t=4.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.64570E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.8065229E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.76748E-02
    12.5% t=5.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.78810E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.7971538E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.74770E-02
    13.0% t=5.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.92640E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.7581478E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.72315E-02
    13.5% t=5.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.04770E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6993123E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.69576E-02
    14.0% t=5.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.14900E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6392262E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.66925E-02
    14.5% t=5.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.23190E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5871651E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.64496E-02
    15.0% t=6.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.29980E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5425379E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.62243E-02
    15.5% t=6.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.35680E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5034774E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.60124E-02
    16.0% t=6.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.40680E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4671752E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.58092E-02
    16.5% t=6.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.45280E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4311275E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.56115E-02
    17.0% t=6.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.49670E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3960321E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.54210E-02
    17.5% t=7.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.54000E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3618374E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.52375E-02
    18.0% t=7.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.58200E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3293265E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.50617E-02
    18.5% t=7.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.62340E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2999722E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.48955E-02
    19.0% t=7.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.66330E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2747114E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.47402E-02
    19.5% t=7.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.70190E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2537562E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.45960E-02
    20.0% t=8.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.73910E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2363530E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.44612E-02
    20.5% t=8.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.77470E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2214278E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.43339E-02
    21.0% t=8.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.80880E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2096630E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.42158E-02
    21.5% t=8.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.84130E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2005099E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.41063E-02
    22.0% t=8.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.87220E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1931299E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.40035E-02
    22.5% t=9.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.90140E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1871683E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.39064E-02
    23.0% t=9.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.92890E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1823168E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.38140E-02
    23.5% t=9.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.95460E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1786403E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.37259E-02
    24.0% t=9.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.97830E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1764015E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.36423E-02
    24.5% t=9.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.99980E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1754575E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.35622E-02
    25.0% t=10.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.01900E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1758369E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.34854E-02
    25.5% t=10.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.03570E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1772803E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.34110E-02
    26.0% t=10.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.04990E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1791496E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.33379E-02
    26.5% t=10.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.06150E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1809773E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.32654E-02
    27.0% t=10.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.07060E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1825422E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.31935E-02
    27.5% t=11.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.07700E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1838305E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.31225E-02
    28.0% t=11.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.08080E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1849891E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.30529E-02
    28.5% t=11.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.08180E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1862265E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.29852E-02
    29.0% t=11.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.08000E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1877272E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.29197E-02
    29.5% t=11.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.07520E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1896138E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.28567E-02
    30.0% t=12.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.06760E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1919861E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.27963E-02
    30.5% t=12.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.05710E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1948875E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.27385E-02
    31.0% t=12.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.04360E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1983166E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.26834E-02
    31.5% t=12.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.02720E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2022825E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.26308E-02
    32.0% t=12.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 7.00780E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2068037E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.25808E-02
    32.5% t=13.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.98520E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2118981E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.25335E-02
    33.0% t=13.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.95930E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2176016E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.24890E-02
    33.5% t=13.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.92970E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2239477E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.24475E-02
    34.0% t=13.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.89620E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2309819E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.24091E-02
    34.5% t=13.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.85830E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2387182E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.23740E-02
    35.0% t=14.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.81550E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2471538E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.23420E-02
    35.5% t=14.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.76690E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2562442E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.23133E-02
    36.0% t=14.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.71180E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2659100E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.22876E-02
    36.5% t=14.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.64910E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2762004E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.22652E-02
    37.0% t=14.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.57700E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2872295E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.22463E-02
    37.5% t=15.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.49380E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2993647E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.22318E-02
    38.0% t=15.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.39710E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3139675E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.22245E-02
    38.5% t=15.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.28380E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3321272E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.22265E-02
    39.0% t=15.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 6.15050E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3536111E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.22371E-02
    39.5% t=15.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.99280E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3766234E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.22528E-02
    40.0% t=16.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.80600E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3992330E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.22699E-02
    40.5% t=16.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.58240E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4219833E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.22893E-02
    41.0% t=16.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.31220E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4464621E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.23129E-02
    41.5% t=16.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.98430E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4717814E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.23379E-02
    42.0% t=16.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.58770E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4963211E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.23599E-02
    42.5% t=17.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.11240E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5207390E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.23781E-02
    43.0% t=17.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.55090E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5450226E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.23892E-02
    43.5% t=17.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.90600E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5678758E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.23882E-02
    44.0% t=17.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.20340E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5894174E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.23736E-02
    44.5% t=17.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 1.51570E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6096057E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.23471E-02
    45.0% t=18.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 9.88110E-05,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6272536E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.23120E-02
    45.5% t=18.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 1.00880E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6437449E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.22742E-02
    46.0% t=18.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 1.14930E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6516543E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.22190E-02
    46.5% t=18.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 1.36230E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6492699E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.21518E-02
    47.0% t=18.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 1.61770E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6374054E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.20735E-02
    47.5% t=19.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 1.85320E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.6178708E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.19845E-02
    48.0% t=19.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.05010E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5933100E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.18891E-02
    48.5% t=19.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.20760E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5661466E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.17912E-02
    49.0% t=19.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.33260E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5379668E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.16935E-02
    49.5% t=19.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.43500E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.5097832E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.15975E-02
    50.0% t=20.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.52430E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4821515E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.15038E-02
    50.5% t=20.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.60850E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4553163E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.14125E-02
    51.0% t=20.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.69340E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4289590E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.13230E-02
    51.5% t=20.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.78220E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.4029865E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.12350E-02
    52.0% t=20.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.87610E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3778387E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.11493E-02
    52.5% t=21.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 2.97480E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3536555E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.10661E-02
    53.0% t=21.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.07760E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3303489E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.09854E-02
    53.5% t=21.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.18290E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.3076515E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.09067E-02
    54.0% t=21.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.28960E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2861583E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.08311E-02
    54.5% t=21.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.39620E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2658961E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.07587E-02
    55.0% t=22.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.50180E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2468068E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.06901E-02
    55.5% t=22.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.60540E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2283621E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.06244E-02
    56.0% t=22.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.70720E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.2112345E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.05636E-02
    56.5% t=22.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.80650E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1955046E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.05082E-02
    57.0% t=22.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.90350E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1811715E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.04583E-02
    57.5% t=23.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 3.99800E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1685488E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.04142E-02
    58.0% t=23.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.09030E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1573427E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.03749E-02
    58.5% t=23.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.17980E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1479584E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.03403E-02
    59.0% t=23.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.26650E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1406437E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.03103E-02
    59.5% t=23.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.35010E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1353054E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.02845E-02
    60.0% t=24.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.43040E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1314027E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.02613E-02
    60.5% t=24.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.50720E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1284339E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.02395E-02
    61.0% t=24.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.58020E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1260090E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.02179E-02
    61.5% t=24.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.64940E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1239593E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.01959E-02
    62.0% t=24.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.71450E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1224172E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.01738E-02
    62.5% t=25.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.77540E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1213304E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.01521E-02
    63.0% t=25.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.83200E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1206090E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.01309E-02
    63.5% t=25.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.88410E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1204163E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.01110E-02
    64.0% t=25.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.93160E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1205063E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.00924E-02
    64.5% t=25.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 4.97450E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1206564E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.00748E-02
    65.0% t=26.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.01300E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1207892E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.00582E-02
    65.5% t=26.2 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.04700E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1209055E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.00424E-02
    66.0% t=26.4 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.07640E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1210776E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.00275E-02
    66.5% t=26.6 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.10120E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1214044E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.00136E-02
    67.0% t=26.8 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.12120E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1220395E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 3.00009E-02
    67.5% t=27.0 @ θ≈Δθ Σ|Ψ|ΔηΔθ= 5.13640E-04,  @ 0≤θ≤37Δθ Σ|Ψ|ΔηΔθ= 2.1231150E-02,  @ η≈0.6 Σ|Ψ|ΔηΔθ= 2.99895E-02

#### Combined plot showing evolution of the streamfunction during iteration

```julia
R = reynolds_values[end]
plot!(combined_plot,xtickfont = font(12),ytickfont = font(12), legendfont = font(8), titlefont=font(10), fmt = :svg, legend=:outertopright)
xlabel!(L"\theta"*"-axis \n"*L"N_η=%$N, M_θ=%$M,\Delta t = %$(Δt), ϵ = %$ϵ")
xticks!(([0:π/6:π;], ["0", "π/6", "π/3", "π/2", "2π/3", "5π/6","π"]))
title!(L"Ψ_{ηηt}  = \frac{1}{{R_s }}Ψ _{ηηηη}  + Ψ_{ηηη} Ψ_θ   - Ψ_{ηηθ} Ψ_η +\epsilon\Psi}_{\theta\theta}"*"\n"*L" Ψ(η=0)=Ψ_{ηη}(η=0)=0,\quad Ψ(η=1)=0,\ Ψ_{η}(η=1)=-sinθ  ")
display(combined_plot)
mkpath("R_equals_$(R)")
savefig("R_equals_$(R)/psi_solution_R_$(R)_combined_RE_e_$(round(ϵ,sigdigits=3)).svg")
```

```julia
R = reynolds_values[end]
Plots.default(overwrite_figure=false)
if size(plot_array)[1] > 1
    plot!(plot_array[end-1],plot_array[end],xtickfont = font(12), ytickfont = font(10), titlefont=font(10),fmt = :svg)
    title!(L"N_η=%$N, M_θ=%$M, Δt=%$(Δt), η = %$eta_profile, ϵ = %$ϵ")
    xticks!(([0:π/6:π;], ["0", "π/6", "π/3", "π/2", "2π/3", "5π/6","π"]))
    mkpath("R_equals_$(R)")
    savefig("R_equals_$(R)/psi_normlocation_R_$(R)_RE_e_$(round(ϵ,sigdigits=3)).svg")
end
```

#### Animated wireplot showing time evolution of $\Psi$

```julia
anim_θprofile = Animation()
for i in plot_array
    plot(i,xlims = (0, π), ylims = (0.0, 0.22), xtickfont = font(12), ytickfont = font(10), titlefont=font(10))
    title!(L"N_η=%$N, M_θ=%$M, Δt=%$(Δt), η = %$eta_profile, ϵ = %$ϵ")
    xticks!(([0:π/6:π;], ["0", "π/6", "π/3", "π/2", "2π/3", "5π/6","π"]))
    frame(anim_θprofile)
end

mkpath("R_equals_$(R)")
gif(anim_θprofile, "R_equals_$(R)/anim_theta_profile_evolution_R_$(R)_RE_e_$(round(ϵ,sigdigits=3)).gif", fps = 2)
```

```julia
anim_wireplot = Animation()
for i in plot_arraywf
    plot(i, xtickfont = font(12), ytickfont = font(12), ztickfont = font(12), titlefont= font(11))
    frame(anim_wireplot)
end

gif(anim_wireplot, "R_equals_$(R)/anim_wireframes_R_$(R)_RE_e_$(round(ϵ,sigdigits=3)).mp4", fps = 3)
gif(anim_wireplot, "R_equals_$(R)/anim_wireframes_R_$(R)_RE_e_$(round(ϵ,sigdigits=3)).gif", fps = 3)
```

#### $\eta$-profile plot

```julia
m=4
MatrixPsi=readdlm("psifin.m",Float64,);
eta_steps = size(MatrixPsi)[1]
theta_steps = size(MatrixPsi)[2]
xinterval=range(-1,stop=1,length=eta_steps-2)
θ_scalefactor = round(Int,N/theta_steps)
eta=range(-1, stop=1,length= N+1)

plot(eta, ψ_1st_order[:,m], label="Julia 1st Order", linecolor=:orange, linestyle=:solid, linewidth =2)
plot!(eta,ψ_j[:,m]        , label="Julia 2nd Order ",linecolor=:red,      linestyle=:dot, linewidth =2)
#plot!(x->Ψ_smallr(Δθ*(m-1),x,R,ϵ,3),0,1, label="Small "*L"R_s"*" asymptotic", linestyle=:dot, linewidth =3, linecolor=:blue)

if R < 70
    plot!(x->Ψ_smallr((m-1)*Δθ,x,R, ϵ, 3),-1,1, label="Small "*L"R_s"*" asymptotic", linestyle=:dot, linecolor=:blue, linewidth =3)
else
    plot!(x->Ψ_bigr((m-1)*Δθ,x),-1,1, label="Large R analytical",  linestyle=:dash, linecolor=:blue,fmt = :svg)
end

#plot!(-xinterval,-MatrixPsi[2:end-1,θ_scalefactor*(m-1)+1], label="Fortran FD", linestyle=:dash, linecolor=:black)
#plot!(x->Ψ_asym(Δθ*(m-1),x,R),-1,1,label="Asymmetric analytical", linestyle=:dot, linecolor=:grey)

#Labels
plot!(xtickfont = font(12), ytickfont = font(12),legendfont=font(10))
plot!(title= L"θ=\frac{%$(m-1)}{%$M}π \quad R_s= %$R \quad  ϵ = %$ϵ",size=(1100,500), legend=:outertopright, xlabel ="η \n"*L"N_η=%$N, M_θ=%$M,\Delta t = %$(Δt)", ylabel=L"Ψ", yguidefontrotation=-90)

mkpath("R_equals_$(R)")
savefig("R_equals_$(R)/psi_solution_R_$(R)_vsFortran_RE_e_$(round(ϵ,sigdigits=3)).svg")
```

#### $\theta$-profile plot

```julia
eta_profile =0.6
delta_eta_steps = 2/(eta_steps-3)
theta=range(0, stop=pi,length= M+1)
theta2=range(0, stop=pi,length= theta_steps)

plot_julia = plot(theta, ψ_1st_order[round(Int,(eta_profile+1)/Δη)+1,:], linecolor=:orange, label="Julia 1st Order", linestyle=:solid, linewidth=2)
plot!(plot_julia, theta ,ψ_j[round(Int,(eta_profile+1)/Δη)+1,:], linecolor=:red, label="Julia 2nd Order", linestyle=:dot, linewidth=2)

if R < 70
    plot!(x->Ψ_smallr(x,eta_profile,R, ϵ,3),0,pi, label="Small "*L"R_s"*" asymptotic", linestyle=:dot, linecolor=:blue, linewidth =3)
else
    plot!(x->Ψ_bigr(x,eta_profile),0,pi, label="Large R analytical",  linestyle=:dash, linecolor=:blue)
end

#plot!(theta2,MatrixPsi[round(Int,(eta_profile+1)/delta_eta_steps)+2,:], linestyle=:dash, label="Fortran winding",linecolor=:black,fmt = :svg)

#Labels
xticks!(plot_julia,([0:π/6:π;], ["0", "π/6", "π/3", "π/2", "2π/3", "5π/6","π"]))
title!(plot_julia,L"θ"*"-profile at "*L"η= %$eta_profile, \ R_s = %$R, \ ϵ = %$ϵ")
plot!(xtickfont = font(12), ytickfont = font(12),legendfont=font(10))
plot!(xlabel = "θ \n"*L"N_η=%$N, M_θ=%$M,\Delta t = %$(Δt)", ylabel = L"Ψ"*"\n",size=(1000,500), yguidefontrotation=-90, legend=:outertopright)

mkpath("R_equals_$(R)")
savefig("R_equals_$(R)/psi_solution_R_$(R)_thetaprofile01_RE_e_$(round(ϵ,sigdigits=3)).svg")
```

```julia
eta_profile =0.6
theta=range(0, stop=pi,length= M+1)
julia_theta_profile = plot(theta,ψ_j[round(Int,(eta_profile+1)/Δη)+1,:],linecolor=:blue , label="Julia R =$R", linestyle=:solid, fmt = :svg)
scatter!(julia_theta_profile,theta,ψ_j[round(Int,(eta_profile+1)/Δη)+1,:],linecolor=:blue , label="Julia R =$R", markersize=4)
plot!(julia_theta_profile,xticks=([0:π/6:π;], ["0", "π/6", "π/3", "π/2", "2π/3", "5π/6","π"]), title=L"θ"*" profile at "*L"η= %$eta_profile, \  ϵ = %$ϵ",size=(1000,500),legend=:outertopright, ylabel = L"Ψ"*"\n",yguidefontrotation=-90)
xlabel!("θ \n"*L"N_η=%$N, M_θ=%$M,\Delta t = %$(Δt)")
plot!(xtickfont = font(12), ytickfont = font(12),legendfont=font(10))

mkpath("R_equals_$(R)")
savefig("R_equals_$(R)/psi_solution_R_$(R)_thetaprofile02_RE_e_$(round(ϵ,sigdigits=3)).svg")
```

#### Streamfunction plotted in 3D

```julia
psi_sol = reshape(ψ_j,length(ψ_j));
η_mesh = [(-1 +(n-1)*Δη)  for m=1:M+1 for n=1:N+1];
θ_mesh = [((m-1)*Δθ) for m=1:M+1 for n=1:N+1 ];
η_vector = range(-1,stop = 1,length = N+1);
θ_vector = range(0,stop = pi,length = M+1);
```

```julia
plot(η_mesh,θ_mesh,psi_sol,seriestype=:scatter, markersize = 0.2, marker=:circle,camera=(-20,30), size=(1000,800), label="", fmt = :svg)
yticks!(([0:π/6:π;], ["0", "π/6", "π/3", "π/2", "2π/3", "5π/6","π"]))
plot!(xlabel=L"η", ylabel=L"θ", zlabel=L"Ψ"*"\n", title=L"R_s = %$R,  ϵ = %$ϵ"*"\n"*L"N_η=%$N, M_θ=%$M,\Delta t = %$(Δt)")
plot!(xtickfont = font(12), ytickfont = font(12), ztickfont = font(12),  titlefont=font(10))

mkpath("R_equals_$(R)")
savefig("R_equals_$(R)/psi_solution_R_$(R)_scatter3d_RE_e_$(round(ϵ,sigdigits=3)).svg")
```

```julia
wireframe( range(-1.0,stop = 1.0,length = round(Int,N/8)+1),range(0.0,stop = pi,length = round(Int,M/8)+1), transpose(ψ_j[1:8:end,1:8:end]), colour=:greys, fmt = :svg)
yticks!(([0:π/6:π;], ["0", "π/6", "π/3", "π/2", "2π/3", "5π/6","π"]))
plot!(xlabel=L"\eta", ylabel=L"\theta", zlabel=L"\Psi"*"\n", title=L"R_s = %$R,  ϵ = %$ϵ"*"\n"*L"N_η=%$N, M_θ=%$M,\Delta t = %$(Δt)", size=(1000,800),camera=(-40,10), xlims = (-1, 1), ylims = (0.0, pi) )
plot!(xtickfont = font(12), ytickfont = font(12), ztickfont = font(12), titlefont = font(11))

mkpath("R_equals_$(R)")
savefig("R_equals_$(R)/psi_solution_R_$(R)_wireframe_RE_e_$(round(ϵ,sigdigits=3)).svg")
```

```julia
surface(range(-1,stop = 1,length = round(Int,N/4)+1),range(0,stop = pi,length = round(Int,M/4)+1),transpose(ψ_j[1:4:end,1:4:end]), colour=:redsblues, fmt = :svg)
yticks!(([0:π/6:π;], ["0", "π/6", "π/3", "π/2", "2π/3", "5π/6","π"]))
plot!(xlabel=L"\eta", ylabel=L"\theta", zlabel=L"\Psi"*"\n", title=L"R_s = %$R,  ϵ = %$ϵ"*"\n"*L"N_η=%$N, M_θ=%$M,\Delta t = %$(Δt)", size=(900,800),camera=(-30,20) )
#plot!(st=:contour)
plot!(xtickfont = font(12), ytickfont = font(12), ztickfont = font(12), titlefont = font(11))

mkpath("R_equals_$(R)")
savefig("R_equals_$(R)/psi_solution_R_$(R)_surface_RE_e_$(round(ϵ,sigdigits=3)).svg")
```

#### Contour plot

```julia
contour(range(-1,stop = 1,length = round(Int,N/2)+1),range(0,stop = pi,length = round(Int,M/2)+1),transpose(ψ_j[1:2:end,1:2:end]), colour=:redsblues, fill=true, fmt= :svg, levels=50)
yticks!(([0:π/6:π;], ["0", "π/6", "π/3", "π/2", "2π/3", "5π/6","π"]))
plot!(xlabel=L"\eta", ylabel=L"\theta", title="Ψ at "*L"R_s = %$R, N_η=%$N, M_θ=%$M,\Delta t = %$(Δt), , ϵ = %$(ϵ)", size=(1000,800),camera=(-30,20))
plot!(yguidefontrotation=-90)
plot!(xtickfont = font(12), ytickfont = font(12), titlefont = font(11))
arrow_scalefactor = 0.2
for n=2:8:N
    η = -1+(n-1)*Δη
    for m =2:8:M
        θ = (m-1)*Δθ
        arrow_x = (ψ_j[n,m+1]-ψ_j[n,m])*arrow_scalefactor/Δθ
        arrow_y = -(ψ_j[n+1,m]-ψ_j[n-1,m])*arrow_scalefactor/(2*Δη)
        if abs(arrow_x) > 0.1
            arrow_x = arrow_x*arrow_scalefactor/abs(arrow_x)
        end
        if abs(arrow_y) > 0.1
            arrow_y = arrow_y*arrow_scalefactor/abs(arrow_y)
        end
        quiver!([(η,θ)],quiver=[(arrow_x,arrow_y)], arrow =0.2, linecolor=:black)
    end
end
mkpath("R_equals_$(R)")
savefig("R_equals_$(R)/psi_solution_R_$(R)_contour_RE.svg")
```

#### Plots of $\eta$-derivatives (checking for boundary layers)

```julia
function ψ_FD_ηηηη(ψ::Matrix{Float64}, n::Int64, m::Int64)
    return (ψ[n-2,m] -    4*ψ[n-1,m]  + 6*ψ[n,m] -  4*ψ[n+1,m]   + ψ[n+2,m])
end

function ψ_FD_ηηη(ψ::Matrix{Float64}, n::Int64, m::Int64)
    return (-ψ[n-2,m]/2 +     ψ[n-1,m]      -ψ[n+1,m]   + ψ[n+2,m]/2)
end

function ψ_FD_ηη(ψ::Matrix{Float64}, n::Int64, m::Int64)
    return (-ψ[n-2,m]/12 +    4*ψ[n-1,m]/3   -5*ψ[n,m]/2 +  4*ψ[n+1,m]/3   - ψ[n+2,m]/12)
end

function ψ_FD_η(ψ::Matrix{Float64}, n::Int64, m::Int64)
    return (ψ[n-2,m]/12 -     2*ψ[n-1,m]/3   +2*ψ[n+1,m]/3   - ψ[n+2,m]/12)
end

function ψ_FD_ηηθθ(ψ::Matrix{Float64}, n::Int64, m::Int64 )
    return ((ψ[n-1,m-1]-2*ψ[n,m-1] + ψ[n+1,m-1]) -2*(ψ[n-1,m]-2*ψ[n,m] + ψ[n+1,m]) + (ψ[n-1,m+1]-2*ψ[n,m+1] + ψ[n+1,m+1]))
end
```

```julia
m = 20 #Thetastep
fourth_deriv=[ψ_FD_ηηηη(ψ_j,i,m) for i= 3:N-1];
third_deriv=[ψ_FD_ηηη(ψ_j,i,m) for i= 3:N-1];
second_deriv=[ψ_FD_ηη(ψ_j,i,m) for i= 3:N-1];
first_deriv=[ψ_FD_η(ψ_j,i,m) for i= 3:N-1];
damped_deriv=[ψ_FD_ηηθθ(ψ_j,i,m) for i= 3:N-1];

eta_values=[-1+i*Δη for i= 3:N-1];

title_string = " at θ=$(round(Δθ*(m-1),digits=1))\u1D9C, "*L"R_s="*" $R"*", ϵ = $(ϵ)"
plot1 = plot(eta_values,first_deriv/Δη,label="timemarched", ylabel=L"ψ_η", title=L"ψ_η"*title_string, xlabel="η", linecolor=:red)
plot2 = plot(eta_values,second_deriv/Δη^2,label="timemarched", ylabel=L"ψ_{ηη}", title=L"ψ_{ηη}"*title_string,xlabel="η", linecolor=:red)
plot3 = plot(eta_values,third_deriv/Δη^3,label="timemarched", ylabel=L"ψ_{ηηη}", title=L"ψ_{ηηη}"*title_string,xlabel="η", linecolor=:red)
plot4 = plot(eta_values,fourth_deriv/Δη^4,label="timemarched", ylabel=L"ψ_{ηηηη}", title=L"ψ_{ηηηη}"*title_string,xlabel="η", linecolor=:red)
plot5 = plot(eta_values, [(ψ_j[n,m+1]-ψ_j[n,m])/Δθ for n=3:N-1 ], title=L"ψ_{θ}"*title_string,label="timemarched" , linestyle=:dot, linewidth=2, linecolor=:red, xlabel="η")
plot6 = plot(eta_values, [(ψ_FD_ηη(ψ_j,n,m+1)-ψ_FD_ηη(ψ_j,n,m))/(Δθ*Δη^2) for n=3:N-1 ], title=L"ψ_{ηηθ}"*title_string,label="timemarched" , linecolor=:red,linewidth=2, linestyle=:dot, xlabel="η")
plot7 = plot(theta, ψ_j[round(Int,(eta_profile+1)/Δη)+1,:], linecolor=:red, label="DNS", linestyle=:dot, linewidth=2)
plot8 = plot(eta_values,damped_deriv/(Δη*Δθ)^2,label="timemarched", ylabel=L"ψ_{ηηθθ}", title=L"ψ_{ηηθθ}"*title_string,xlabel="η", linecolor=:red)
xlabel!(plot7,"θ")
ylabel!(plot7,"Ψ", yguidefontrotation=-90)
xticks!(plot7, ([0:π/6:π;], ["0", "π/6", "π/3", "π/2", "2π/3", "5π/6","π"]))
vline!(plot7, [(m-1)*Δθ],label=" \nDerivatives calc. \n here at θ = $(round((m-1)*Δθ,digits=2))", linewidth=3)

if R < 90
     plot!(plot1,    x-> Ψ_η_smallr(Δθ*(m-1), x ,R), -1.0,1.0, linecolor=:blue, label="Asymptotic", linestyle=:dash, legend=:outertopleft)
     plot!(plot2,   x-> Ψ_ηη_smallr(Δθ*(m-1), x ,R), -1.0,1.0, linecolor=:blue,label="Asymptotic",linestyle=:dash,legend=:outertopleft)
     plot!(plot3,  x-> Ψ_ηηη_smallr(Δθ*(m-1), x ,R), -1.0,1.0, linecolor=:blue,label="Asymptotic", linestyle=:dash,legend=:outertopleft)
     plot!(plot4, x-> Ψ_ηηηη_smallr(Δθ*(m-1), x ,R), -1.0,1.0, linecolor=:blue,label="Asymptotic", linestyle=:dash,legend=:outertopleft)
     plot!(plot5, x-> Ψ_θ_smallr(Δθ*(m-1), x ,R), -1.0,1.0, linecolor=:blue,label="Asymptotic", linestyle=:dash,legend=:outertopleft)
     plot!(plot6, x-> Ψ_ηηθ_smallr(Δθ*(m-1), x ,R), -1.0,1.0, linecolor=:blue,label="Asymptotic", linestyle=:dash,legend=:outertopleft)
    #plot!(ψ_ηηθ_plt,   x-> Ψ_ηηθ_smallr(Δθ*(m-1), x ,rey_number), 0.0,1.0, linecolor=:blue, label="Asymptotic", legend=false)
     #plot!(ψ_θ_plt,   x-> Ψ_θ_smallr(Δθ*(m-1), x ,rey_number), 0.0,1.0, linecolor=:blue, label="Asymptotic",legend=:outertopright)
end

grid_of_plots= plot(plot1, plot2, plot3, plot4,plot5, plot6,plot7,plot8, layout = (4, 2),  size=(1100,1200),xtickfont = font(12), ytickfont = font(12), titlefont = font(12), yguidefontsize=14)

mkpath("R_equals_$(R)")
savefig("R_equals_$(R)/psi_derivatives_R_$(R)_RE_e_$(round(ϵ,sigdigits=3)).svg")

```

```julia
plot(ψ_next[:,1])
```

```julia
sin(1*(-pi)+pi)
```

```julia
 Ψ_smallr(0.5*(-pi)+pi,-1.0+Δη*(64-1),R_initial,ϵ,3)
```

```julia

```


```python
import numpy as np
```

```python
import sympy as sym
from math import *
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import time
from IPython.display import HTML
from scipy import optimize
import cvxopt
# from ipopt import minimize_ipopt
```

    In /home/sashankmns/.local/lib/python3.6/site-packages/matplotlib/mpl-data/stylelib/_classic_test.mplstyle:
    The text.latex.preview rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.
    In /home/sashankmns/.local/lib/python3.6/site-packages/matplotlib/mpl-data/stylelib/_classic_test.mplstyle:
    The mathtext.fallback_to_cm rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.
    In /home/sashankmns/.local/lib/python3.6/site-packages/matplotlib/mpl-data/stylelib/_classic_test.mplstyle: Support for setting the 'mathtext.fallback_to_cm' rcParam is deprecated since 3.3 and will be removed two minor releases later; use 'mathtext.fallback : 'cm' instead.
    In /home/sashankmns/.local/lib/python3.6/site-packages/matplotlib/mpl-data/stylelib/_classic_test.mplstyle:
    The validate_bool_maybe_none function was deprecated in Matplotlib 3.3 and will be removed two minor releases later.
    In /home/sashankmns/.local/lib/python3.6/site-packages/matplotlib/mpl-data/stylelib/_classic_test.mplstyle:
    The savefig.jpeg_quality rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.
    In /home/sashankmns/.local/lib/python3.6/site-packages/matplotlib/mpl-data/stylelib/_classic_test.mplstyle:
    The keymap.all_axes rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.
    In /home/sashankmns/.local/lib/python3.6/site-packages/matplotlib/mpl-data/stylelib/_classic_test.mplstyle:
    The animation.avconv_path rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.
    In /home/sashankmns/.local/lib/python3.6/site-packages/matplotlib/mpl-data/stylelib/_classic_test.mplstyle:
    The animation.avconv_args rcparam was deprecated in Matplotlib 3.3 and will be removed two minor releases later.

```python
# q1 = sym.Symbol('theta_1')
# q2 = sym.Symbol('theta_2')
# q3 = sym.Symbol('theta_3')
# q4 = sym.Symbol('theta_4')
m1 = 1
m2 = 1
l1 = 1
l2 = 1
lc1 = l1/2
lc2= l2/2
I1 = m1*l1**2/12
I2 = m2*l2**2/12
g=9.81

```

```python
def cost_calc(Q,qddot,dt):
    global cost
    q1=Q[0,0]
    q2=Q[1,0]
    q3=Q[2,0]
    q4=Q[3,0]
    M_mat = np.array([[I1 + I2 + m2*l1**2 + 2*m2*l1*lc2*cos(q2), I2 + m2*l1*lc2*cos(q2)],[I2 + m2*l1*lc2*cos(q2), I2]])
    C_mat = np.array([[-2*m2*l1*lc2*sin(q2)*q4, -m2*l1*lc2*sin(q2)*q4],[m2*l1*lc2*sin(q2)*q3, 0]])
    Tor_mat = np.array([[-m1*g*lc1*sin(q1) - m2*g*(l1*sin(q1) + lc2*sin(q1+q2))],[-m2*g*lc2*sin(q1+q2)]])
    U = (M_mat @ qddot).reshape(qddot.shape) + C_mat @ np.array([[q3],[q4]]) - Tor_mat
    return np.linalg.norm(U,axis=0)
```

```python
def state_transition(Q,q1ddot,dt):
    global cost,t,tlast
    q1=Q[0,0]
    q2=Q[1,0]
    q3=Q[2,0]
    q4=Q[3,0]
    U = np.array([[0],[0]])
#     print(q1ddot.shape)
    M_mat = np.array([[I1 + I2 + m2*l1**2 + 2*m2*l1*lc2*cos(q2), I2 + m2*l1*lc2*cos(q2)],[I2 + m2*l1*lc2*cos(q2), I2]])
    C_mat = np.array([[-2*m2*l1*lc2*sin(q2)*q4, -m2*l1*lc2*sin(q2)*q4],[m2*l1*lc2*sin(q2)*q3, 0]])
    Tor_mat = np.array([[-m1*g*lc1*sin(q1) - m2*g*(l1*sin(q1) + lc2*sin(q1+q2))],[-m2*g*lc2*sin(q1+q2)]])
    U = (M_mat @ q1ddot).reshape(q1ddot.shape) + C_mat @ Q[2:,0,None] - Tor_mat
#     print(U.shape)
    dot_mat = np.linalg.inv(M_mat) @ (Tor_mat + U - C_mat @ np.array([[q3],[q4]]))
    dot_mat.reshape(2,1)
    f = np.block([[q3],[q4],[dot_mat]])
    if t>tlast + 2:
        tlast=t
        print(round(t), end=' ')

    return Q + f*dt
```

```python
def state_transition_func(Q,U):
    global cost,t,tlast
    q1=Q[0]
    q2=Q[1]
    q3=Q[2]
    q4=Q[3]
    U =U.reshape(2,1)
#     U = np.array([[0],[0]])
#     print(q1ddot.shape)
    M_mat = np.array([[I1 + I2 + m2*l1**2 + 2*m2*l1*lc2*cos(q2), I2 + m2*l1*lc2*cos(q2)],[I2 + m2*l1*lc2*cos(q2), I2]])
    C_mat = np.array([[-2*m2*l1*lc2*sin(q2)*q4, -m2*l1*lc2*sin(q2)*q4],[m2*l1*lc2*sin(q2)*q3, 0]])
    Tor_mat = np.array([[-m1*g*lc1*sin(q1) - m2*g*(l1*sin(q1) + lc2*sin(q1+q2))],[-m2*g*lc2*sin(q1+q2)]])
#     U = (M_mat @ q1ddot).reshape(q1ddot.shape) + C_mat @ Q[2:,0,None] - Tor_mat
#     print(U.shape)
    dot_mat = np.linalg.inv(M_mat) @ (Tor_mat + U - C_mat @ np.array([[q3],[q4]]))
    dot_mat = dot_mat.flatten()
    f = np.array([q3,q4,dot_mat[0], dot_mat[1]])
    return f
```

```python
import numpy as np
a=np.array([1,23,5,4,5,3,2,3])
b=np.where((a>=5) | (a<=2))[0]
# np.linalg.norm(a[b])
b
a[b+1]
```

    array([23,  5,  4,  3,  3])

```python
def obj_func(X):
    sum=0;
    global del_t
    i = np.arange(X.shape[0]);
    i = np.where((i < X.shape[0]-12) & ((i+1+7)%12==0))[0]
    sum = del_t/6.0*(np.linalg.norm(X[i])**2 + np.linalg.norm(X[i+1])**2 + 4*(np.linalg.norm(X[i+6])**2 + np.linalg.norm(X[i+1+6])**2) + np.linalg.norm(X[i+12])**2 + np.linalg.norm(X[i+1+12])**2)
#       if (i+1+7)%12==0:
#         sum=sum+del_t/6.0*(X[i]**2 + X[i+1]**2 + 4*(X[i+6]**2 + X[i+1+6]**2) + X[i+12]**2 + X[i+1+12]**2)
    return sum
```

```python
def callback(xk,state):
    plt.plot([0,state.nit],[0,0],linewidth=4)
    plt.show(block=False)
```

```python
# def interpol_constraints(Q,i,del_t):
#     boola
#     return boolarray.flatten()
# def collocation_constraints(Q,i,del_t):
#     boolarray =
#     return boolarray.flatten()
arrr = np.array([(1,1)]*10)
arr2 = np.array([1]*6 + [0]*4)
# arrr[:,0] = arr2

a=inf
a
def wrap_angle(angle):
    while abs(angle) > np.pi:
        angle= angle-np.sign(angle)*2*np.pi
    return angle
```

```python
del_t = 0.2
tf = 2;
q01 = pi/2
q02 = 0
qf1 = -pi/2
qf2 = 0
qdot1des = 1;
qdot2des = -1;

if qdot1des!=0:
    while np.sign(qf1-q01)!=np.sign(qdot1des):
        qf1 = qf1 + np.sign(qdot1des)*2*pi;
if qdot2des!=0:
    while np.sign(qf2-q02)!=np.sign(qdot2des):
        qf2 = qf2 + np.sign(qdot2des)*2*pi;
# q_init = np.block([[np.linspace(-pi/2,pi/2,tf/del_t)],[np.zeros((1,tf/del_t))],[],[]])
q0 = np.array([[q01],[q02],[0],[0]]);
qf = np.array([[qf1],[qf2],[0],[0]]);
Q0 = np.block([[q0[0,0] + (qf[0,0]-q0[0,0])*np.arange(0,tf+del_t/2,del_t/2)/(tf)],[q0[1,0] + (qf[1,0]-q0[1,0])*np.arange(0,tf+del_t/2,del_t/2)/(tf)],[q0[2,0] + (qf[2,0]-q0[2,0])*np.arange(0,tf+del_t/2,del_t/2)/(tf)],[q0[3,0] + (qf[3,0]-q0[3,0])*np.arange(0,tf+del_t/2,del_t/2)/(tf)],[0*np.arange(0,tf+del_t/2,del_t/2)],[0*np.arange(0,tf+del_t/2,del_t/2)]])
Q0 = Q0.T.flatten()

i = np.arange(Q0.shape[0]);
objind = np.where((i < Q0.shape[0]-12) & ((i+1+7)%12==0))[0]
objind2 = np.where((i-1 < Q0.shape[0]-12) & ((i-1+1+7)%12==0))[0]
objind3 = np.where((i-6 < Q0.shape[0]-12) & ((i-6+1+7)%12==0))[0]
objind4 = np.where((i-1-6 < Q0.shape[0]-12) & ((i-1-6+1+7)%12==0))[0]
objind5 = np.where((i-12 < Q0.shape[0]-12) & ((i-12+1+7)%12==0))[0]
objind6 = np.where((i-1-12 < Q0.shape[0]-12) & ((i-1-12+1+7)%12==0))[0]
hess_arr = np.zeros((Q0.shape[0],Q0.shape[0]))
hess_arr[objind,objind] = del_t/6.0
hess_arr[objind2,objind2] = del_t/6.0
hess_arr[objind3,objind3] = 4*del_t/6.0
hess_arr[objind4,objind4] = 4*del_t/6.0
hess_arr[objind5,objind5] = del_t/6.0
hess_arr[objind6,objind6] = del_t/6.0
Q0.shape
# np.arange(0,tf+del_t/2,del_t/2)
# Q=Q0
qf
# interpolarray = 0.5*(Q[a:a+4] + Q[a+12:a+12+4]) + del_t/8.0*(state_transition_func(Q[a:a+4],Q[a+4:a+6]) - state_transition_func(Q[a+12:a+12+4],Q[a+12+4:a+12+6])) - Q[a+6:a+6+4]
# interpolarray
```

    array([[ 4.71238898],
           [-6.28318531],
           [ 0.        ],
           [ 0.        ]])

```python
# bounds_array = np.array([(-inf,inf)]*Q0.shape[0])
equalityconstraints = [];
boundaryconstraints = [];
inputconstraints = [];
pathconstraints = [];
umin = -10000
umax = 10000
# bounds_array[0:4,0] = q0
# bounds_array[0:4,1] = q0
# bounds_array[-6:-2,0] = q0
# bounds_array[-6:-2,1] = qf
def bound_constraint(Q):
    return Q[-6] - qf[0,0]
boundaryconstraints.append({"type" : "eq" , "fun" : bound_constraint})
def bound_constraint(Q):
    return Q[-5] - qf[1,0]
boundaryconstraints.append({"type" : "eq" , "fun" : bound_constraint})
def bound_constraint(Q):
    return Q[-4] - qf[2,0]
boundaryconstraints.append({"type" : "eq" , "fun" : bound_constraint})
def bound_constraint(Q):
    return Q[-3] - qf[3,0]
boundaryconstraints.append({"type" : "eq" , "fun" : bound_constraint})
def bound_constraint(Q):
    return Q[0] - q0[0,0]
boundaryconstraints.append({"type" : "eq" , "fun" : bound_constraint})
def bound_constraint(Q):
    return Q[1] - q0[1,0]
boundaryconstraints.append({"type" : "eq" , "fun" : bound_constraint})
def bound_constraint(Q):
    return Q[2] - q0[2,0]
boundaryconstraints.append({"type" : "eq" , "fun" : bound_constraint})
def bound_constraint(Q):
    return Q[3] - q0[3,0]
boundaryconstraints.append({"type" : "eq" , "fun" : bound_constraint})
for i in range(Q0.shape[0]-11):
    if i%12==0:
        def input_constraint(Q,i=i):
            return np.linalg.norm(Q[i+4:i+6])-umin
        inputconstraints.append({"type" : "ineq" , "fun" : input_constraint})
        def input_constraint(Q,i=i):
            return -np.linalg.norm(Q[i+4:i+6])+umax
        inputconstraints.append({"type" : "ineq" , "fun" : input_constraint})
        def input_constraint(Q,i=i):
            return np.linalg.norm(Q[i+4+6:i+6+6])-umin
        inputconstraints.append({"type" : "ineq" , "fun" : input_constraint})
        def input_constraint(Q,i=i):
            return -np.linalg.norm(Q[i+4+6:i+6+6])+umax
        inputconstraints.append({"type" : "ineq" , "fun" : input_constraint})
#         def path_constraint(Q,i=i):
#             return Q[i+3]#*qdot2des
#         pathconstraints.append({"type" : "ineq" , "fun" : path_constraint})
#         def path_constraint(Q,i=i):
#             return Q[i+3+6]*qdot2des
#         pathconstraints.append({"type" : "eq" , "fun" : path_constraint})
#         def path_constraint(Q,i=i):
#             return Q[i+2]*qdot1des
#         pathconstraints.append({"type" : "ineq" , "fun" : path_constraint})
#         def path_constraint(Q,i=i):
#             return Q[i+2+6]*qdot1des
#         pathconstraints.append({"type" : "ineq" , "fun" : path_constraint})
        if i<Q0.shape[0]-17:
            for j in range(4):
                def interpol_constraint(Q,a=i,b=j):
                    global del_t
                    interpolarray = 0.5*(Q[a:a+4] + Q[a+12:a+12+4]) + del_t/8.0*(state_transition_func(Q[a:a+4],Q[a+4:a+6]) - state_transition_func(Q[a+12:a+12+4],Q[a+12+4:a+12+6])) - Q[a+6:a+6+4]
                    return interpolarray.flatten()[b]
                def collocation_constraint(Q,a=i,b=j):
                    global del_t
                    collocationarray = (Q[a:a+4] - Q[a+12:a+12+4]) + del_t/6.0*(state_transition_func(Q[a:a+4],Q[a+4:a+6]) + state_transition_func(Q[a+12:a+12+4],Q[a+12+4:a+12+6]) +4*state_transition_func(Q[a+6:a+6+4],Q[a+6+4:a+6+6]))
                    return collocationarray.flatten()[b]
                equalityconstraints.append({"type" : "eq" , "fun" : interpol_constraint});
                equalityconstraints.append({"type" : "eq" , "fun" : collocation_constraint});

constraints_array = boundaryconstraints+equalityconstraints+inputconstraints + pathconstraints
print(len(boundaryconstraints),len(inputconstraints),len(equalityconstraints),len(constraints_array))
print(len(boundaryconstraints + equalityconstraints))
```

    8 40 80 128
    88

```python
opt_res = optimize.minimize(obj_func,Q0, jac = lambda x,mat=hess_arr : mat @ x, hess = lambda x : hess_arr,constraints=constraints_array,options={"maxiter" :10000})
Q_star =opt_res.x
# np.cos(Q_star)
```

    /home/sashankmns/.local/lib/python3.6/site-packages/scipy/optimize/_minimize.py:523: RuntimeWarning: Method SLSQP does not use Hessian information (hess).
      RuntimeWarning)

```python
Q_sol = Q_star.reshape(round(Q_star.shape[0]/6),6)
print(opt_res.success)
print(opt_res.message)
print(opt_res.nit)
print("control effort : " + str(opt_res.fun))
print("jacobian norm : " + str(np.linalg.norm(opt_res.jac)))
inputs = np.linalg.norm(Q_sol[:,4:6],axis=1)
print("Max control input : " + str((np.argmax(inputs)/Q_sol.shape[0]*(tf),inputs.max())))
# np.linalg.norm(Q_sol[:,4:6])
print(Q_sol[:,:])
# Q_sol.shape
q =Q_sol[0,0:4].reshape(4,1)
plt.plot([0,l1*sin(q[0,0]),l1*sin(q[0,0])+l2*sin(q[1,0]+q[0,0])],[0,-l1*cos(q[0,0]),-l1*cos(q[0,0]) -l2*cos(q[1,0]+q[0,0])],'-k',linewidth=2)
```

```python
def animate(i):
    global t, tf , q, u,del_t,l1,l2,Q_star,tlast,j
    if t[-1]<=tf+del_t/4 and j<=Q_sol.shape[0]:
        ax = plt.gca();
        ax.clear();
        q1ddot = 2*np.array([[-pi/2-q[0,0]],[0-q[1,0]]]) + 6*np.array([[-q[2,0]],[-q[3,0]]])
#         q = state_transition(q,q1ddot,0.01)
        q = Q_sol[j,0:4].reshape(4,1)
        if j == 0:
            q = Q_sol[0,0:4].reshape(4,1)
#         plt.clear()
        ax.plot([0,l1*sin(q[0,0]),l1*sin(q[0,0])+l2*sin(q[1,0]+q[0,0])],[0,-l1*cos(q[0,0]),-l1*cos(q[0,0]) -l2*cos(q[1,0]+q[0,0])],'-k',linewidth=2)
        ax.set_xlim([0-l1-l2,0+l1+l2])
        ax.set_ylim([0-l1-l2,0+l1+l2])
        if abs(t[-1]-0) < del_t/2:
            print(q.flatten(),j,t)
        t=np.append(t,t[-1]+del_t/2);
        j=j+1
        if abs(t[-1]-0) < del_t/2:
            print(q.flatten(),j,t)
        if t[-1]>=int(tlast)+2:
            tlast = int(t[-1])
```

```python
fig = plt.figure()
t=np.array([0]);
j=0
tlast=-2
q = np.zeros((4,1));
ani = animation.FuncAnimation(fig, animate, frames = Q_sol.shape[0], interval=del_t/2*1000)
HTML(ani.to_html5_video())
# print(t[-1])
```

```python
fig = plt.figure()
plt.plot(t[0:-1], np.linalg.norm(Q_sol[:,4:6],axis=1))
plt.plot(t[0:-1], Q_sol[:,5])
plt.show()
wrap_angle(11.2)
```

```python
def obj_fun2(X):
    return np.sum(np.sin(X))
```

```python
constraints2 = [];
def thisfun(X,b=0.4):
    return cos(X[0])-b
def constraint1(X):
    return cos(X[0]) - 0.1
constraints2.append({"type":"ineq","fun" : constraint1})
def constraint1(X):
    return cos(X[1]) - 0.2
constraints2.append({"type":"ineq","fun" : constraint1})
def constraint1(X):
    return thisfun(X)
constraints2.append({"type":"ineq","fun" : constraint1})

Q20 = np.pi,np.pi
#  jac = lambda x,mat=hess_arr : mat @ x ,
# constraints=boundaryconstraints+equalityconstraints+inputconstraints
```

```python
# ani = animation.FuncAnimation(fig, animate,frames = int((tf-t)/0.01), interval=20, blit=True)
# while t<tf:
# #     global t, tf , q, u
# #     ax=plt.gca()
# #     ax.clear()
# #     plt.clf()
#     u = 10*np.array([[-pi/2-q[0,0]],[0]])
#     q = state_transition(q,u,0.01)
#     t=t+0.01;
#     print("time is : %s "%(t))
# #         plt.clear()
# #     plt.show(block=False)
# #     time.sleep(0.2)
# plt.plot([0,l1*sin(q[0,0]),l1*sin(q[0,0])+l2*sin(q[1,0]+q[0,0])],[0,-l1*cos(q[0,0]),-l1*cos(q[0,0])-l2*cos(q[1,0]+q[0,0])],'-k',linewidth=2)
# plt.xlim([0-l1-l2,0+l1+l2])
# plt.ylim([0-l1-l2,0+l1+l2])
# plt.show()
print(q[0,0],t)
# fig2 = plt.figure()
# plt.plot([0,l1*sin(q[0,0]),l1*sin(q[0,0])+l2*sin(q[1,0]+q[0,0])],[0,-l1*cos(q[0,0]),-l1*cos(q[0,0])-l2*cos(q[1,0]+q[0,0])],'-k',linewidth=2)
# plt.xlim([0-l1-l2,0+l1+l2])
# plt.ylim([0-l1-l2,0+l1+l2])

```

```python
t=0;
tf=100;
q1 = -pi/2
q3 = 0
while q1<pi/2:
    q=np.array([[q1],[0],[q3],[0]])
    qddot=np.block([[np.linspace(-I1*pi/2,I1*pi/2)],[np.zeros((1,50))]])
    cost_arr = cost_calc(q,qddot,0.01)
    q=np.array([[q1],[-2*q1],[q3],[-2*q3]])
    qddot[1,:] = -2*qddot[0,:]
    cost_arr2 = cost_calc(q,qddot,0.01)
    if not (cost_arr>=cost_arr2).all():
        break;
    q1 = q1+0.03
print(q1)
print(cost_arr>=cost_arr2)

```

    -0.010796326794895394
    [ True  True  True  True  True  True  True  True  True  True  True  True
      True  True  True  True  True  True  True  True  True  True  True  True
      True  True  True  True  True  True  True  True  True  True  True  True
      True  True False False False False False False False False False False
     False False]

```python

```

```python

```