Exemple #1
0
def FFT_ibvp(t_span: list, x_span: list, Nt: int, Nx: int,
             ic: callable(float)):
    """
    Fast calculate exact solution
    :param t_span:
    :param x_span:
    :param Nt:
    :param Nx:
    :param ic:
    :return:
    """
    a = x_span[0]
    b = x_span[1]
    t0 = t_span[0]
    tf = t_span[1]
    c = 2 * b - a
    x_span = np.linspace(a, b, 2 * Nx + 1)[:-1]
    extend_x_span = np.linspace(a, c, 4 * Nx + 1)[:-1]
    t_span = np.linspace(t0, tf, Nt)
    # xsample = np.linspace(2*a-b, b, 2* Nx +1 )[:-1]
    icsample = np.array([ic(x) for x in x_span])
    ghostsample = np.flip(
        np.array([ic(x) for x in np.linspace(a, b, 2 * Nx + 1)]), 0)[:-1]
    extend_icsample = np.hstack([icsample, ghostsample])

    phasesample = np.array(
        [np.exp(-1j * np.pi * x / 2) for x in extend_x_span])
    invphasesample = np.array(
        [np.exp(1j * np.pi * x / 2) for x in extend_x_span])

    hsample = extend_icsample * phasesample
    hhat = np.fft.ifftshift(np.fft.fft(hsample))
    ysample = np.array([extend_icsample]).T

    # phasesample = np.array([np.exp(-1j * np.pi * x/ 2) for x in x_span])
    # invphasesample = np.array([np.exp(1j * np.pi * x/ 2) for x in x_span])
    # hsample = icsample * phasesample
    # hhat = np.fft.ifftshift(np.fft.fft(hsample))
    # ysample = np.array([icsample]).T
    print(hhat.shape)
    for t in t_span[1:]:
        evolsample = np.array([
            np.exp(-pow(np.pi * (n + 0.5), 2) * t)
            for n in range(-2 * Nx, 2 * Nx)
        ])
        htsmaple = np.fft.ifft(np.fft.fftshift(hhat * evolsample))
        utsample = np.array([invphasesample * htsmaple])
        ysample = np.hstack([ysample, utsample.T])

    print(ysample.shape)
    print(x_span.shape, t_span.shape, ysample.shape)
    sol_extended = OdeResult(t=t_span, y=np.real(ysample))
    sol = OdeResult(t=t_span[:], y=np.real(ysample[0:2 * Nx, :]))
    PlotSpaceTimePDE(sol_extended,
                     xsample=extend_x_span,
                     title="FFT sol on extended region for dx={:.2g}".format(
                         1 / 1024),
                     xcount=50,
                     tcount=50)
    PlotSpaceTimePDE(sol,
                     xsample=x_span,
                     title="FFT correct sol for dx={:.2g}".format(1 / 1024),
                     xcount=25,
                     tcount=50)
    Write_sol_json(sol=sol, file_name="FFT for tf={}.json".format(tf))
    return sol, x_span
Exemple #2
0
def LTEplot2D(grid_size=[4, 8, 16, 32, 64, 128],
              axis: str = 't',
              norm_type: str = "L1"):
    def d(x):
        return 2 + np.cos(np.pi * x)

    def q(x):
        return 0.0

    def bc0(t):
        return 1 + np.exp(-(np.pi**2) * t / 4)

    def bc1(t):
        return -0.5 * np.pi * (1 + np.exp(-(np.pi**2) * t / 4))

    def ic(x):
        return 2 * np.cos(0.5 * np.pi * x)

    def f(x, t):
        result =  -1/ 4 * (np.pi ** 2) * np.exp(- (np.pi ** 2) * t / 4) \
                * np.cos(x * np.pi/2)*(-1 + 3 *(1 + np.exp((np.pi ** 2) * t / 4))* np.cos(x * np.pi))
        return result

    def exact_sol(x, t):
        return (1 + np.exp(-(np.pi**2) * t / 4)) * np.cos(np.pi * x / 2)

    a = 0
    b = 1
    t_span = [0, 0.25]
    methods = ["CN", "Ralston"]
    markdict = {4: 'x', 8: 'x', 16: 'x', 32: 'x', 64: 'x', 128: 'x', 256: "x"}
    markoffsetdict = dict(zip(methods, ['', '']))
    for N in grid_size:
        dt = 1 / (8 * N**2)
        BC0 = BoundaryCondition(a, type="D", constraint=bc0)
        BC1 = BoundaryCondition(b, type="N", constraint=bc1)
        spgrid = SpaceGrid(a, b, N + 1)
        xsample = np.linspace(a, b, N + 1)
        # initialize the SturmLiouville system and initial-boundary value problem
        ST = SturmLiouville(spgrid, d, q)
        ibvp = IBVP(ST=ST, Nonlinear=None, IC=ic, BCs=[BC0, BC1], rhs=f)
        # compute the discretization and matrix involved
        ibvp.compute()
        for method in methods:
            json_name = "sol node={}, dt={:.2g}, for {}.json".format(
                N, dt, method)
            print(json_name)
            import os
            exists = os.path.isfile('../data/{}'.format(json_name))
            if exists:
                # Store configuration file values
                sol = Read_sol_json(json_name)
            else:
                # Keep presets
                if (method in ["CN", "BE"]):
                    sol = ibvp.customize_solve(t_span=t_span,
                                               type=method,
                                               max_step=dt)
                else:
                    sol = ibvp.ibvp_solve(t_span=t_span,
                                          type=method,
                                          max_step=dt)
                Write_sol_json(sol, json_name)
            ysample = np.abs(sol.y -
                             np.array([[exact_sol(x, t) for t in sol.t]
                                       for x in xsample]))[1:, 1:]
            tsample = sol.t[1:]
            sliced_xsample = xsample[1:]

            sol1 = OdeResult(t=tsample, y=ysample)
            errors = FunctionNormAlong(sol=sol1,
                                       xsample=sliced_xsample,
                                       axis=axis,
                                       type=norm_type)

            if axis == "t":
                plt.semilogy(sliced_xsample,
                             errors,
                             markdict[N] + markoffsetdict[method],
                             label=json_name[4:-5])
            elif axis == "x":
                plt.semilogy(tsample,
                             errors,
                             markdict[N] + markoffsetdict[method],
                             label=json_name[4:-5])
    if axis == 't':
        plt.xlabel("x")
        plt.title("x" + "-error relation in {} norm".format(norm_type))
    else:
        plt.xlabel("t")
        plt.title("t" + "-error relation in {} norm".format(norm_type))
    plt.ylabel("log(error})")
    plt.grid(True)
    plt.legend(loc='center left', bbox_to_anchor=(1, 0.8), shadow=True, ncol=1)

    plt.show()
Exemple #3
0
def Verify2ndAccuracy(grid_size=[4, 8, 16, 32, 64, 128],
                      axis: str = 't',
                      norm_type: str = "L1"):
    def d(x):
        return 2 + np.cos(np.pi * x)

    def q(x):
        return 0.0

    def bc0(t):
        return 1 + np.exp(-(np.pi**2) * t / 4)

    def bc1(t):
        return -0.5 * np.pi * (1 + np.exp(-(np.pi**2) * t / 4))

    def ic(x):
        return 2 * np.cos(0.5 * np.pi * x)

    def f(x, t):
        result =  -1/ 4 * (np.pi ** 2) * np.exp(- (np.pi ** 2) * t / 4) \
                * np.cos(x * np.pi/2)*(-1 + 3 *(1 + np.exp((np.pi ** 2) * t / 4))* np.cos(x * np.pi))
        return result

    def exact_sol(x, t):
        return (1 + np.exp(-(np.pi**2) * t / 4)) * np.cos(np.pi * x / 2)

    a = 0
    b = 1
    t_span = [0, 0.25]
    methods = ["CN", "Ralston"]
    method = methods[0]
    markdict = {4: 'x', 8: 'x', 16: 'x', 32: 'x', 64: 'x', 128: '-', 256: "x"}
    markoffsetdict = dict(zip(methods, ['', '-']))
    errors2d = {"L1": [], "L2": [], "Linf": []}
    for N in grid_size:
        dt = 1 / (8 * N**2)
        BC0 = BoundaryCondition(a, type="D", constraint=bc0)
        BC1 = BoundaryCondition(b, type="N", constraint=bc1)
        spgrid = SpaceGrid(a, b, N + 1)
        xsample = np.linspace(a, b, N + 1)
        # initialize the SturmLiouville system and initial-boundary value problem
        ST = SturmLiouville(spgrid, d, q)
        ibvp = IBVP(ST=ST, Nonlinear=None, IC=ic, BCs=[BC0, BC1], rhs=f)
        # compute the discretization and matrix involved
        ibvp.compute()

        json_name = "sol node={}, dt={:.2g}, for {}.json".format(N, dt, method)
        print(json_name)
        import os
        exists = os.path.isfile('../data/{}'.format(json_name))
        if exists:
            # Store configuration file values
            sol = Read_sol_json(json_name)
        else:
            # Keep presets
            if (method in ["CN", "BE"]):
                sol = ibvp.customize_solve(t_span=t_span,
                                           type=method,
                                           max_step=dt)
            else:
                sol = ibvp.ibvp_solve(t_span=t_span, type=method, max_step=dt)
            Write_sol_json(sol, json_name)
        ysample = np.abs(sol.y - np.array([[exact_sol(x, t) for t in sol.t]
                                           for x in xsample]))[1:, 1:]
        tsample = sol.t[1:]
        sliced_xsample = xsample[1:]

        sol1 = OdeResult(t=tsample, y=ysample)
        errors = FunctionNormAlong(sol=sol1,
                                   xsample=sliced_xsample,
                                   axis=axis,
                                   type=norm_type)
        errors_L1 = FunctionNormAlong(sol=sol1,
                                      xsample=sliced_xsample,
                                      axis=axis,
                                      type="L1")
        errors_L2 = FunctionNormAlong(sol=sol1,
                                      xsample=sliced_xsample,
                                      axis=axis,
                                      type="L2")
        errors_Linf = FunctionNormAlong(sol=sol1,
                                        xsample=sliced_xsample,
                                        axis=axis,
                                        type="Linf")
        errors2d["L1"].append(
            FunctionNorm1D(errors_L1.copy(), 1 / N, type="L1"))
        errors2d["L2"].append(
            FunctionNorm1D(errors_L2.copy(), 1 / N, type="L2"))
        errors2d["Linf"].append(
            FunctionNorm1D(errors_Linf.copy(), 1 / N, type="Linf"))
        if axis == "t":
            offset = {4: 1, 8: 1, 16: 1, 32: 1, 64: 2, 128: 4}[N]
            plt.semilogy(sliced_xsample[::offset],
                         errors[::offset],
                         markdict[N] + markoffsetdict[method],
                         label=json_name[4:-5])
        elif axis == "x":
            plt.semilogy(tsample,
                         errors,
                         markdict[N] + markoffsetdict[method],
                         label=json_name[4:-5])

    # powers = [pow(2, i) for i in range(1,5)]
    for i in [2, 4, 8, 16, 32]:
        plt.semilogy(sliced_xsample,
                     errors * pow(i, 2),
                     '--',
                     label="{} times the node=128 error".format(i))
    if axis == 't':
        plt.xlabel("x")
        plt.title(
            "Verification of 2nd oder accuracy in {} norm".format(norm_type))
    else:
        plt.xlabel("t")
        plt.title(
            "Verification of 2nd oder accuracy in {} norm".format(norm_type))
    plt.ylabel("log(error})")
    plt.grid(True)
    plt.legend(loc='center left', bbox_to_anchor=(1, 0.6), shadow=True, ncol=1)

    plt.show()

    for key in errors2d:
        plt.loglog(grid_size,
                   errors2d[key],
                   'x-',
                   label="total error in 2D-{} norm".format(key))
    plt.loglog(grid_size, [4 * pow(g, -2) for g in grid_size],
               '-',
               label="base line of second oder arruracy")
    # plt.loglog(grid_size, [0.01 * pow(g, -4) for g in grid_size], '-', label="base line of fourth oder arruracy")

    plt.grid(True)
    plt.legend()
    plt.xlabel("node number N")
    plt.ylabel("total errors")
    plt.title(
        "Verification of 2nd order accuracy in 2D norms for {}".format(method))
    plt.show()
Exemple #4
0
def LTEplot3D():
    def d(x):
        return 2 + np.cos(np.pi * x)

    def q(x):
        return 0.0

    def bc0(t):
        return 1 + np.exp(-(np.pi**2) * t / 4)

    def bc1(t):
        return -0.5 * np.pi * (1 + np.exp(-(np.pi**2) * t / 4))

    def ic(x):
        return 2 * np.cos(0.5 * np.pi * x)

    def f(x, t):
        result =  -1/ 4 * (np.pi ** 2) * np.exp(- (np.pi ** 2) * t / 4) \
                * np.cos(x * np.pi/2)*(-1 + 3 *(1 + np.exp((np.pi ** 2) * t / 4))* np.cos(x * np.pi))
        return result

    def exact_sol(x, t):
        return (1 + np.exp(-(np.pi**2) * t / 4)) * np.cos(np.pi * x / 2)

    a = 0
    b = 1
    t_span = [0, 0.25]
    N = 10
    dt = 0.00213
    method = "Ralston"
    BC0 = BoundaryCondition(a, type="D", constraint=bc0)
    BC1 = BoundaryCondition(b, type="N", constraint=bc1)

    spgrid = SpaceGrid(a, b, N + 1)
    xsample = np.linspace(a, b, N + 1)
    # initialize the SturmLiouville system and initial-boundary value problem
    ST = SturmLiouville(spgrid, d, q)
    ibvp = IBVP(ST=ST, Nonlinear=None, IC=ic, BCs=[BC0, BC1], rhs=f)
    # compute the discretization and matrix involved
    ibvp.compute()

    if (method in ["CN", "BE"]):
        sol = ibvp.customize_solve(t_span=t_span, type=method, max_step=dt)
    else:
        sol = ibvp.ibvp_solve(t_span=t_span, type=method, max_step=dt)
    json_name = "sol_test node={}, dt={}, for {}".format(N, dt, method)
    Write_sol_json(sol, json_name + ".json")
    sol1 = Read_sol_json(json_name + ".json")
    PlotSpaceTimePDE(sol1,
                     xsample,
                     title="Space-Time-Solution node={}, dt={}, for {}".format(
                         N, dt, method),
                     tcount=50,
                     xcount=1)

    ysample = np.log10(
        np.abs(sol1.y - np.array([[exact_sol(x, t) for t in sol1.t]
                                  for x in xsample])))
    sol2 = OdeResult(t=sol1.t[1:], y=ysample[1:, 1:])
    PlotSpaceTimePDE(sol2,
                     xsample[1:],
                     title="Space-Time-Error node={}, dt={} for {}".format(
                         N, dt, method),
                     tcount=50,
                     xcount=1,
                     error_plot=True)