def compareStabilityDomains(self, list_rk_names):
        xx,yy = self.re_xx, self.im_yy
        zz = self.eigvals
        x= self.re
        y= self.im


        # ratio_height_over_width = np.abs( (np.max(y)-np.min(y))/(np.max(x)-np.min(x)) )
        # fig, ax = plt.subplots(1,1,dpi=80, figsize=(8, 8*ratio_height_over_width))
        fig, ax = plt.subplots(1,1,dpi=300)
        # plot des axes Im et Re
        ax.plot([np.min(x), np.max(x)], [0,0], color=(0,0,0), linestyle='--', linewidth=0.4)
        ax.plot([0,0], [np.min(y), np.max(y)], color=(0,0,0), linestyle='--', linewidth=0.4)

        ## Axis description
        fig.suptitle(f'Domaines de stabilité')
        ax.set_xlabel(r'Re$(\lambda\Delta t)$')
        ax.set_ylabel(r'Im$(\lambda\Delta t)$')

        colors = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan']
        for i,name in enumerate(list_rk_names):
            print(name)
            method = rk_coeffs.getButcher(name)
            A,b,c = method['A'], method['b'], method['c']
            if np.size(b)>6:
              bSympy=False # c'est plus rapide d'éviter Sympy, on dirait qu'il n'arrive pas à calculer les détermiannts analytiquement...
            else:
              bSympy=True
            Rfun, Rsym = self.computeStabilityFunction(A,b,c,bSympy=bSympy)
            RR   = Rfun(zz)
            rr = np.abs(RR) # ratio d'augmentation

            current_color=colors[i]
            # add stability domain
            ax.contour(xx,yy,rr,levels=[0,1],colors=current_color)

            # hachurer en rouge la zone instable
            # rr_sup_1 = np.where(np.abs(rr) >= 1)
            # temp = np.zeros_like(rr)
            # temp[rr_sup_1] = 1.
            # plt.rcParams['hatch.color']=current_color  # seul moyen que j'ai trouvé pour avoir des hachures rouges...
            # cs   = ax.contourf(xx,yy, temp, levels=[0,0.5,1.5],  #levels=[0., 1.0, 1.5],
            #                  hatches=[None,'\\\\', '\\\\'], alpha = 0.)
            # plt.rcParams['hatch.color']=[0,0,0]
        # add legend
        proxy = [plt.Rectangle((0,0),1,1,fc = colors[i]) for i in range(len(list_rk_names))]
        ax.legend(proxy, list_rk_names)
        # ax.axis('equal')

if __name__=='__main__':
    # Setup warnings such that any problem with complex number raises an error
    import warnings
    warnings.simplefilter("error", np.ComplexWarning) #to ensure we are not dropping complex perturbations

    # Choose the area of the complex plane that will be analysed
    # test = testPrecision(re_min=-100, re_max=100, im_min=0., im_max=100, n_re=1000, n_im=1001) # on aperçoit des formes intriguantes en terme d'iso-contour de précision
    # test = testPrecision(re_min=-10, re_max=10, im_min=-5, im_max=5, n_re=200, n_im=202)
    # test = testPrecision(re_min=-20, re_max=20, im_min=-20, im_max=20, n_re=200, n_im=202)
    # test = testPrecision(re_min=-3, re_max=3, im_min=-3, im_max=3, n_re=200, n_im=202)
    test = testPrecision(re_min=-6, re_max=6, im_min=-6, im_max=6, n_re=200, n_im=202)

    #%% Show the precision and stability of a given RK method
    method = rk_coeffs.getButcher('Radau5')
    # method = rk_coeffs.getButcher('RK45')
    A,b,c = method['A'], method['b'], method['c']
    
    # A,b,c = reverseRK(A,b,c)
    
    # tracé du contour de la précision par rapport à l'exponentielle
    pprecision, pprecision2 = test.plotStabilityRegionRK(A,b,c, bSympy=False)
    R, Rsym = test.computeStabilityFunction(A,b,c, bSympy=False)

    # calcul du rayon spectral
    eigvals = np.linalg.eigvals(A)
    rho = np.max(np.abs(eigvals))
    print('spectral radius: rho=', rho)
    print('R(rho)=', R(rho))
    print('R(1/rho)=', R(1/rho))
    solref = scipy.integrate.solve_ivp(fun=modelfun,
                                       y0=x_0,
                                       t_span=T,
                                       method='Radau',
                                       t_eval=None,
                                       vectorized=False,
                                       rtol=1e-12,
                                       atol=1e-12,
                                       jac=None)
    if solref.status != 0:
        raise Exception('ODE integration failed: {}'.format(solref.message))
    t_end = pytime.time()
    print('DIRK computed in {} s'.format(t_end - t_start))

    #### compute solution with DIRK
    A, b, c = rk_coeffs.getButcher('L-SDIRK-33')
    t_start = pytime.time()
    sol_dirk = DIRK_integration(f=modelfun,
                                y0=x_0,
                                t_span=T,
                                nt=nt_dirk,
                                A=A,
                                b=b,
                                c=c,
                                options=None,
                                gradF=gradF,
                                bRosenbrockApprox=False,
                                bUseCustomNewton=True)
    t_end = pytime.time()
    print('DIRK computed in {} s'.format(t_end - t_start))
示例#4
0
        nt = 20
    elif problemtype=='stiff': #  Hirschfelder-Curtiss
        print('Testing time integration routines with Hirschfelder-Curtiss stiff equation')
        k=100
        def modelfun(t,x):
            """ Mass-spring system"""
            return -k*(x-np.sin(t))
        y0 = np.array((0.3,1))
        tf = 5.0
        nt = 100
    elif problemtype=='dae': # DAE simple : y1'=y1, 0=y1+y2
        raise Exception('TODO: DAEs are not yet compatible with the chosen formulation: need to add mass matrix to the problem formulation')
    elif problemtype=='pde':
        raise Exception('TODO')

    method = rk_coeffs.getButcher(name=name)
    if mod=='DIRK': # DIRK solve
        sol = DIRK_integration(fun=modelfun, y0=y0, t_span=[0., tf], nt=nt,
                                    method=method, jacfun=None)
    elif mod=='FIRK': # FIRK solve
        sol = FIRK_integration(fun=modelfun, y0=y0, t_span=[0., tf], nt=nt,
                                    method=method, jacfun=None)
    elif mod=='ERK': # FIRK solve
        sol = ERK_integration(fun=modelfun, y0=y0, t_span=[0., tf], nt=nt,
                                    method=method)
    elif mod=='reverseERK':
        sol = inverseERKintegration(fun=modelfun, y0=y0, t_span=[0,tf], nt=nt,
                                    method=method, jacfun=None, bPrint=True,
                                    fullDebug=True, bPlotSubsteps=True)
    elif mod=='adapt_ERK':
        sol = ERK_adapt_integration(fun=modelfun, y0=y0, t_span=[0.,tf], method=method, first_step=1e-2,
示例#5
0
         t_eval=None,  #np.linspace(0,tf,5),
         dense_output=False,
         # jac_sparsity=jacSparsity,
         jac=jacfun,
         events=None,
         vectorized=False,
         args=None)
 else:
     from integration_esdirk import FIRK_integration, DIRK_integration, ERK_integration
     import rk_coeffs
     method = 'Radau5'
     mod = 'FIRK'
     # method='IE'; mod ='DIRK'
     # method='L-SDIRK-33'; mod ='DIRK'
     nt = 100
     A, b, c = rk_coeffs.getButcher(name=method)
     if mod == 'DIRK':  # DIRK solve
         out = DIRK_integration(
             fun=lambda t, x: modelfun(t=t, z=x, options=options),
             y0=y0,
             t_span=[0., tf],
             nt=nt,
             A=A,
             b=b,
             c=c,
             jacfun=jacfun)
     elif mod == 'FIRK':  # FIRK solve
         out = FIRK_integration(
             fun=lambda t, x: modelfun(t=t, z=x, options=options),
             y0=y0,
             t_span=[0., tf],
示例#6
0
from bruss_1D import brusselator_1d
### SETUP MODEL ###
xmin = 0
xmax = 4
nx = 1000
dx = (xmax - xmin) / (nx + 1)
x = np.linspace(xmin + dx, xmax - dx, nx)
bz1d = brusselator_1d(nx=nx)
fcn = bz1d.fcn
yini = bz1d.init()
nvar = 2

# Setup time integation interval and method
tini = 0.
tend = 2.0
method = rk_coeffs.getButcher('ESDIRK43B')

# Create a function to efficiently compute the system's Jacobian
if 0:
    import scipy.optimize
    from scipy.sparse import diags
    width = np.ceil(nvar * 1.5).astype(int)
    offsets = range(
        -width,
        width)  # positions of the diagonals with respect to the main diagonal
    diagonals = [np.ones((nvar * bz1d.nx - abs(i), )) for i in offsets]
    sparsity = diags(diagonals, offsets)
    groups = scipy.optimize._numdiff.group_columns(sparsity)

    def jac_sparse(t, x):
        return scipy.sparse.csc_matrix(
示例#7
0
                         np.log10(np.abs(expp / self.x0)),
                         levels=map_levels)  #, cmap = 'gist_earth')
        fig2.colorbar(cs)
        ax.contour(xx, yy, rr, levels=[0, 1], colors='r')
        ax.set_title('expansion ratio of numerical solution')
        return pprecision, pprecision2

if __name__ == '__main__':
    import warnings
    warnings.simplefilter(
        "error", np.ComplexWarning
    )  #to ensure we are not dropping complex perturbations

    ## test RK stability region
    N = 200
    A, b, c = rk_coeffs.getButcher(
        'rk4')  #54A-V4') #'RadauIIA-5')#'L-SDIRK-33') #SDIRK4()5L[1]SA-1')

    #    plotStabilityRegionRK_old(A,b,c, re_min=-5, re_max=10, im_min=-5, im_max=5, n_re=N, n_im=N+2 )

    test = testPrecision(re_min=-10,
                         re_max=10,
                         im_min=-5,
                         im_max=5,
                         n_re=N,
                         n_im=N + 2,
                         x0=1)
    #    test =             testPrecision(re_min=-20, re_max=20, im_min=-20, im_max=20, n_re=N, n_im=N+2, x0=1)
    pprecision, pprecision2 = test.plotStabilityRegionRK(A, b, c, nt=10)

    # estimate R(+\infty)
    R = test.functionStabilityPolynomial(A, b, c)