Example #1
1
def comparison_plot(f, u, Omega, filename='tmp.pdf',
                    plot_title='', ymin=None, ymax=None,
                    u_legend='approximation'):
    """Compare f(x) and u(x) for x in Omega in a plot."""
    x = sm.Symbol('x')
    print 'f:', f

    f = sm.lambdify([x], f, modules="numpy")
    u = sm.lambdify([x], u, modules="numpy")
    if len(Omega) != 2:
        raise ValueError('Omega=%s must be an interval (2-list)' % str(Omega))
    # When doing symbolics, Omega can easily contain symbolic expressions,
    # assume .evalf() will work in that case to obtain numerical
    # expressions, which then must be converted to float before calling
    # linspace below
    if not isinstance(Omega[0], (int,float)):
        Omega[0] = float(Omega[0].evalf())
    if not isinstance(Omega[1], (int,float)):
        Omega[1] = float(Omega[1].evalf())

    resolution = 401  # no of points in plot
    xcoor = linspace(Omega[0], Omega[1], resolution)
    # Vectorized functions expressions does not work with
    # lambdify'ed functions without the modules="numpy"
    exact  = f(xcoor)
    approx = u(xcoor)
    plot(xcoor, approx, '-')
    hold('on')
    plot(xcoor, exact, '-')
    legend([u_legend, 'exact'])
    title(plot_title)
    xlabel('x')
    if ymin is not None and ymax is not None:
        axis([xcoor[0], xcoor[-1], ymin, ymax])
    savefig(filename)
Example #2
0
def non_physical_behavior(I, a, T, dt, theta):
    """
    Given lists/arrays a and dt, and numbers I, dt, and theta,
    make a two-dimensional contour line B=0.5, where B=1>0.5
    means oscillatory (unstable) solution, and B=0<0.5 means
    monotone solution of u'=-au.
    """
    a = np.asarray(a)
    dt = np.asarray(dt)  # must be arrays
    B = np.zeros((len(a), len(dt)))  # results
    for i in range(len(a)):
        for j in range(len(dt)):
            u, t = solver(I, a[i], T, dt[j], theta)
            # Does u have the right monotone decay properties?
            correct_qualitative_behavior = True
            for n in range(1, len(u)):
                if u[n] > u[n - 1]:  # Not decaying?
                    correct_qualitative_behavior = False
                    break  # Jump out of loop
            B[i, j] = float(correct_qualitative_behavior)
    a_, dt_ = st.ndgrid(a, dt)  # make mesh of a and dt values
    st.contour(a_, dt_, B, 1)
    st.grid('on')
    st.title('theta=%g' % theta)
    st.xlabel('a')
    st.ylabel('dt')
    st.savefig('osc_region_theta_%s.png' % theta)
    st.savefig('osc_region_theta_%s.eps' % theta)
Example #3
0
    def plot(self, include_exact=True, plt=None):
        """
        Add solver.u curve to scitools plotting object plt,
        and include the exact solution if include_exact is True.
        This plot function can be called several times (if
        the solver object has computed new solutions).
        """
        if plt is None:
            import scitools.std as plt

        plt.plot(self.solver.t, self.solver.u, '--o')
        plt.hold('on')
        theta = self.solver.get('theta')
        theta2name = {0: 'FE', 1: 'BE', 0.5: 'CN'}
        name = theta2name.get(theta, '')
        legends = ['numerical %s' % name]
        if include_exact:
            t_e = np.linspace(0, self.problem.get('T'), 1001)
            u_e = self.problem.exact_solution(t_e)
            plt.plot(t_e, u_e, 'b-')
            legends.append('exact')
        plt.legend(legends)
        plt.xlabel('t')
        plt.ylabel('u')
        dt = self.solver.get('dt')
        plt.title('theta=%g, dt=%g' % (theta, dt))
        plt.savefig('%s_%g.png' % (name, dt))
        return plt
Example #4
0
def demo():
    """
    Demonstrate difference between Euler-Cromer and the
    scheme for the corresponding 2nd-order ODE.
    """
    I = 1.2
    V = 0.2
    m = 4
    b = 0.2
    s = lambda u: 2 * u
    F = lambda t: 0
    w = np.sqrt(2.0 / 4)  # approx freq
    dt = 0.9 * 2 / w  # longest possible time step
    w = 0.5
    P = 2 * pi / w
    T = 4 * P
    from vib import solver as solver2
    import scitools.std as plt

    for k in range(4):
        u2, t2 = solver2(I, V, m, b, s, F, dt, T, "quadratic")
        u, v, t = solver(I, V, m, b, s, F, dt, T, "quadratic")
        plt.figure()
        plt.plot(t, u, "r-", t2, u2, "b-")
        plt.legend(["Euler-Cromer", "centered scheme"])
        plt.title("dt=%.3g" % dt)
        raw_input()
        plt.savefig("tmp_%d" % k + ".png")
        plt.savefig("tmp_%d" % k + ".pdf")
        dt /= 2
Example #5
0
def comparison_plot(u, Omega, u_e=None, filename='tmp.eps',
                    plot_title='', ymin=None, ymax=None):
    x = sp.Symbol('x')
    u = sp.lambdify([x], u, modules="numpy")
    if len(Omega) != 2:
        raise ValueError('Omega=%s must be an interval (2-list)' % str(Omega))
    # When doing symbolics, Omega can easily contain symbolic expressions,
    # assume .evalf() will work in that case to obtain numerical
    # expressions, which then must be converted to float before calling
    # linspace below
    if not isinstance(Omega[0], (int,float)):
        Omega[0] = float(Omega[0].evalf())
    if not isinstance(Omega[1], (int,float)):
        Omega[1] = float(Omega[1].evalf())

    resolution = 401  # no of points in plot
    xcoor = linspace(Omega[0], Omega[1], resolution)
    # Vectorized functions expressions does not work with
    # lambdify'ed functions without the modules="numpy"
    approx = u(xcoor)
    plot(xcoor, approx)
    legends = ['approximation']
    if u_e is not None:
        exact  = u_e(xcoor)
        hold('on')
        plot(xcoor, exact)
        legends = ['exact']
    legend(legends)
    title(plot_title)
    xlabel('x')
    if ymin is not None and ymax is not None:
        axis([xcoor[0], xcoor[-1], ymin, ymax])
    savefig(filename)
Example #6
0
def run_solvers_and_plot(solvers, rhs, T, dt, title=''):
    Nt = int(round(T / float(dt)))
    t_mesh = np.linspace(0, T, Nt + 1)
    t_fine = np.linspace(0, T, 8 * Nt + 1)  # used for very accurate solution

    legends = []
    solver_exact = odespy.RK4(rhs)

    for solver in solvers:
        solver.set_initial_condition([rhs.I, 0])
        u, t = solver.solve(t_mesh)

        solver_name = 'CrankNicolson' if solver.__class__.__name__ == \
                      'MidpointImplicit' else solver.__class__.__name__

        if len(t_mesh) <= 50:
            plt.plot(t, u[:, 0])  # markers by default
        else:
            plt.plot(t, u[:, 0], '-2')  # no markers
        plt.hold('on')
        legends.append(solver_name)

    # Compare with RK4 on a much finer mesh
    solver_exact.set_initial_condition([rhs.I, 0])
    u_e, t_e = solver_exact.solve(t_fine)

    plt.plot(t_e, u_e[:, 0], '-')  # avoid markers by spec. line type
    legends.append('exact (RK4, dt=%g)' % (t_fine[1] - t_fine[0]))
    plt.legend(legends, loc='upper right')
    plt.xlabel('t')
    plt.ylabel('u')
    plt.title(title)
    plotfilestem = '_'.join(legends)
    plt.savefig('tmp_%s.png' % plotfilestem)
    plt.savefig('tmp_%s.pdf' % plotfilestem)
def demo():
    """
    Demonstrate difference between Euler-Cromer and the
    scheme for the corresponding 2nd-order ODE.
    """
    I = 1.2
    V = 0.2
    m = 4
    b = 0.2
    s = lambda u: 2 * u
    F = lambda t: 0
    w = np.sqrt(2. / 4)  # approx freq
    dt = 0.9 * 2 / w  # longest possible time step
    w = 0.5
    P = 2 * pi / w
    T = 4 * P
    from vib import solver as solver2
    import scitools.std as plt
    for k in range(4):
        u2, t2 = solver2(I, V, m, b, s, F, dt, T, 'quadratic')
        u, v, t = solver(I, V, m, b, s, F, dt, T, 'quadratic')
        plt.figure()
        plt.plot(t, u, 'r-', t2, u2, 'b-')
        plt.legend(['Euler-Cromer', 'centered scheme'])
        plt.title('dt=%.3g' % dt)
        raw_input()
        plt.savefig('tmp_%d' % k + '.png')
        plt.savefig('tmp_%d' % k + '.pdf')
        dt /= 2
Example #8
0
    def plot(self, include_exact=True, plt=None):
        """
        Add solver.u curve to the plotting object plt,
        and include the exact solution if include_exact is True.
        This plot function can be called several times (if
        the solver object has computed new solutions).
        """
        if plt is None:
            import scitools.std  as plt # can use matplotlib as well

        plt.plot(self.solver.t, self.solver.u, '--o')
        plt.hold('on')
        theta2name = {0: 'FE', 1: 'BE', 0.5: 'CN'}
        name = theta2name.get(self.solver.theta, '')
        legends = ['numerical %s' % name]
        if include_exact:
            t_e = linspace(0, self.problem.T, 1001)
            u_e = self.problem.exact_solution(t_e)
            plt.plot(t_e, u_e, 'b-')
            legends.append('exact')
        plt.legend(legends)
        plt.xlabel('t')
        plt.ylabel('u')
        plt.title('theta=%g, dt=%g' %
                  (self.solver.theta, self.solver.dt))
        plt.savefig('%s_%g.png' % (name, self.solver.dt))
        return plt
Example #9
0
def run_solvers_and_plot(solvers, rhs, T, dt, title=''):
    Nt = int(round(T/float(dt)))
    t_mesh = np.linspace(0, T, Nt+1)
    t_fine = np.linspace(0, T, 8*Nt+1)  # used for very accurate solution

    legends = []
    solver_exact = odespy.RK4(rhs)

    for solver in solvers:
        solver.set_initial_condition([rhs.I, 0])
        u, t = solver.solve(t_mesh)

        solver_name = 'CrankNicolson' if solver.__class__.__name__ == \
                      'MidpointImplicit' else solver.__class__.__name__

        if len(t_mesh) <= 50:
            plt.plot(t, u[:,0])             # markers by default
        else:
            plt.plot(t, u[:,0], '-2')       # no markers
        plt.hold('on')
        legends.append(solver_name)

    # Compare with RK4 on a much finer mesh
    solver_exact.set_initial_condition([rhs.I, 0])
    u_e, t_e = solver_exact.solve(t_fine)

    plt.plot(t_e, u_e[:,0], '-') # avoid markers by spec. line type
    legends.append('exact (RK4, dt=%g)' % (t_fine[1]-t_fine[0]))
    plt.legend(legends, loc='upper right')
    plt.xlabel('t');  plt.ylabel('u')
    plt.title(title)
    plotfilestem = '_'.join(legends)
    plt.savefig('tmp_%s.png' % plotfilestem)
    plt.savefig('tmp_%s.pdf' % plotfilestem)
Example #10
0
def non_physical_behavior(I, a, T, dt, theta):
    """
    Given lists/arrays a and dt, and numbers I, dt, and theta,
    make a two-dimensional contour line B=0.5, where B=1>0.5
    means oscillatory (unstable) solution, and B=0<0.5 means
    monotone solution of u'=-au.
    """
    a = np.asarray(a); dt = np.asarray(dt)  # must be arrays
    B = np.zeros((len(a), len(dt)))         # results
    for i in range(len(a)):
        for j in range(len(dt)):
            u, t = solver(I, a[i], T, dt[j], theta)
            # Does u have the right monotone decay properties?
            correct_qualitative_behavior = True
            for n in range(1, len(u)):
                if u[n] > u[n-1]:  # Not decaying?
                    correct_qualitative_behavior = False
                    break  # Jump out of loop
            B[i,j] = float(correct_qualitative_behavior)
    a_, dt_ = st.ndgrid(a, dt)  # make mesh of a and dt values
    st.contour(a_, dt_, B, 1)
    st.grid('on')
    st.title('theta=%g' % theta)
    st.xlabel('a'); st.ylabel('dt')
    st.savefig('osc_region_theta_%s.png' % theta)
    st.savefig('osc_region_theta_%s.pdf' % theta)
Example #11
0
def visualize(list_of_curves, legends, title='', filename='tmp'):
    """Plot list of curves: (u, t)."""
    for u, t in list_of_curves:
        plt.plot(t, u)
        plt.hold('on')
    plt.legend(legends)
    plt.xlabel('t')
    plt.ylabel('u')
    plt.title(title)
    plt.savefig(filename + '.png')
    plt.savefig(filename + '.pdf')
    plt.show()
Example #12
0
def visualize(u, t, title='', filename='tmp'):
    plt.plot(t, u, 'b-')
    plt.xlabel('t')
    plt.ylabel('u')
    dt = t[1] - t[0]
    plt.title('dt=%g' % dt)
    umin = 1.2*u.min(); umax = 1.2*u.max()
    plt.axis([t[0], t[-1], umin, umax])
    plt.title(title)
    plt.savefig(filename + '.png')
    plt.savefig(filename + '.pdf')
    plt.show()
Example #13
0
def visualize(list_of_curves, legends, title='', filename='tmp'):
    """Plot list of curves: (u, t)."""
    for u, t in list_of_curves:
        plt.plot(t, u)
        plt.hold('on')
    plt.legend(legends)
    plt.xlabel('t')
    plt.ylabel('u')
    plt.title(title)
    plt.savefig(filename + '.png')
    plt.savefig(filename + '.pdf')
    plt.show()
Example #14
0
def visualize(u, t, title='', filename='tmp'):
    plt.plot(t, u, 'b-')
    plt.xlabel('t')
    plt.ylabel('u')
    dt = t[1] - t[0]
    plt.title('dt=%g' % dt)
    umin = 1.2*u.min(); umax = 1.2*u.max()
    plt.axis([t[0], t[-1], umin, umax])
    plt.title(title)
    plt.savefig(filename + '.png')
    plt.savefig(filename + '.pdf')
    plt.show()
Example #15
0
def visualize(u, t, title="", filename="tmp"):
    plt.plot(t, u, "b-")
    plt.xlabel("t")
    plt.ylabel("u")
    dt = t[1] - t[0]
    plt.title("dt=%g" % dt)
    umin = 1.2 * u.min()
    umax = 1.2 * u.max()
    plt.axis([t[0], t[-1], umin, umax])
    plt.title(title)
    plt.savefig(filename + ".png")
    plt.savefig(filename + ".pdf")
    plt.show()
Example #16
0
def run_solvers_and_plot(solvers, timesteps_per_period=20, num_periods=1, b=0):
    w = 2 * np.pi  # frequency of undamped free oscillations
    P = 2 * np.pi / w  # duration of one period
    dt = P / timesteps_per_period
    Nt = num_periods * timesteps_per_period
    T = Nt * dt
    t_mesh = np.linspace(0, T, Nt + 1)
    t_fine = np.linspace(0, T, 8 * Nt + 1)  # used for very accurate solution

    legends = []
    solver_exact = odespy.RK4(f)

    for solver in solvers:
        solver.set_initial_condition([solver.users_f.I, 0])
        u, t = solver.solve(t_mesh)

        solver_name = 'CrankNicolson' if solver.__class__.__name__ == \
                      'MidpointImplicit' else solver.__class__.__name__

        # Make plots (plot last 10 periods????)
        if num_periods <= 80:
            plt.figure(1)
            if len(t_mesh) <= 50:
                plt.plot(t, u[:, 0])  # markers by default
            else:
                plt.plot(t, u[:, 0], '-2')  # no markers
            plt.hold('on')
            legends.append(solver_name)

    # Compare with exact solution plotted on a very fine mesh
    #t_fine = np.linspace(0, T, 10001)
    #u_e = solver.users_f.exact(t_fine)
    # Compare with RK4 on a much finer mesh
    solver_exact.set_initial_condition([solver.users_f.I, 0])
    u_e, t_e = solver_exact.solve(t_fine)

    if num_periods < 80:
        plt.figure(1)
        plt.plot(t_e, u_e[:, 0], '-')  # avoid markers by spec. line type
        legends.append('exact (RK4)')
        plt.legend(legends, loc='upper left')
        plt.xlabel('t')
        plt.ylabel('u')
        plt.title('Time step: %g' % dt)
        plt.savefig('vib_%d_%d_u.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.eps' % (timesteps_per_period, num_periods))
def run_solvers_and_plot(solvers, timesteps_per_period=20,
                         num_periods=1, b=0):
    w = 2*np.pi    # frequency of undamped free oscillations
    P = 2*np.pi/w  # duration of one period
    dt = P/timesteps_per_period
    Nt = num_periods*timesteps_per_period
    T = Nt*dt
    t_mesh = np.linspace(0, T, Nt+1)
    t_fine = np.linspace(0, T, 8*Nt+1)  # used for very accurate solution

    legends = []
    solver_exact = odespy.RK4(f)

    for solver in solvers:
        solver.set_initial_condition([solver.users_f.I, 0])
        u, t = solver.solve(t_mesh)

        solver_name = 'CrankNicolson' if solver.__class__.__name__ == \
                      'MidpointImplicit' else solver.__class__.__name__

        # Make plots (plot last 10 periods????)
        if num_periods <= 80:
            plt.figure(1)
            if len(t_mesh) <= 50:
                plt.plot(t, u[:,0])             # markers by default
            else:
                plt.plot(t, u[:,0], '-2')       # no markers
            plt.hold('on')
            legends.append(solver_name)

    # Compare with exact solution plotted on a very fine mesh
    #t_fine = np.linspace(0, T, 10001)
    #u_e = solver.users_f.exact(t_fine)
    # Compare with RK4 on a much finer mesh
    solver_exact.set_initial_condition([solver.users_f.I, 0])
    u_e, t_e = solver_exact.solve(t_fine)

    if num_periods < 80:
        plt.figure(1)
        plt.plot(t_e, u_e[:,0], '-') # avoid markers by spec. line type
        legends.append('exact (RK4)')
        plt.legend(legends, loc='upper left')
        plt.xlabel('t');  plt.ylabel('u')
        plt.title('Time step: %g' % dt)
        plt.savefig('vib_%d_%d_u.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.eps' % (timesteps_per_period, num_periods))
def logistic():
    problem = Logistic(alpha=0.2, R=1, U0=0.1)
    T = 40
    solver = ForwardEuler(problem)
    solver.set_initial_condition(problem.U0)
    t = np.linspace(0, T, 401)  # 400 intervals in [0,T]
    u, t = solver.solve(t)
    # Note that import * is not legal inside functions so we
    # have to import each specific function.
    from scitools.std import plot, hardcopy, xlabel, ylabel, title
    plot(t, u)
    xlabel('t'); ylabel('u')
    title('Logistic growth: alpha=%s, R=%g, dt=%g' \
          % (problem.alpha, problem.R, t[1]-t[0]))
    # Compare with exponential growth
    #from scitools.std import hold, linspace, exp
    #te = linspace(0, dt*N, N+1)
    #ue = 0.1*exp(0.2*te)
    #hold('on')
    #plot(te, ue)
    hardcopy('tmp.eps')
Example #19
0
def logistic():
    problem = Logistic(alpha=0.2, R=1, U0=0.1)
    T = 40
    method = ForwardEuler(problem)
    method.set_initial_condition(problem.U0)
    t = np.linspace(0, T, 401)  # 400 intervals in [0,T]
    u, t = method.solve(t)
    # Note that import * is not legal inside functions so we
    # have to import each specific function.
    from scitools.std import plot, hardcopy, xlabel, ylabel, title
    plot(t, u)
    xlabel('t'); ylabel('u')
    title('Logistic growth: alpha=%s, R=%g, dt=%g' \
          % (problem.alpha, problem.R, t[1]-t[0]))
    # Compare with exponential growth
    #from scitools.std import hold, linspace, exp
    #te = linspace(0, dt*N, N+1)
    #ue = 0.1*exp(0.2*te)
    #hold('on')
    #plot(te, ue)
    hardcopy('tmp.eps')
Example #20
0
def logistic():
    problem = Logistic(0.2, 1, 0.1)
    T = 40
    dt = 0.1
    method = ForwardEuler(problem, dt)
    method.set_initial_condition(problem.u0, 0)
    u, t = method.solve(T)
    # note that import * is not legal inside functions so we
    # have to import each specific function:
    from scitools.std import plot, hardcopy, xlabel, ylabel, title
    plot(t, u)
    xlabel('t'); ylabel('u')
    title('Logistic growth: alpha=0.2, dt=%g, %d steps' \
          % (dt, len(u)-1))
    # compare with exponential growth:
    #from scitools.std import hold, linspace, exp
    #te = linspace(0, dt*N, N+1)
    #ue = 0.1*exp(0.2*te)
    #hold('on')
    #plot(te, ue)
    hardcopy('tmp.eps')
Example #21
0
def plot_boundaries(outer_boundary, inner_boundaries=[], marked_points=None):
    if not isinstance(inner_boundaries, (tuple, list)):
        inner_boundaries = [inner_boundaries]
    boundaries = [outer_boundary]
    boundaries.extend(inner_boundaries)

    # Find max/min of plotting area
    plot_area = [
        min([b.x.min() for b in boundaries]),
        max([b.x.max() for b in boundaries]),
        min([b.y.min() for b in boundaries]),
        max([b.y.max() for b in boundaries]),
    ]

    aspect = (plot_area[3] - plot_area[2]) / (plot_area[1] - plot_area[0])
    for b in boundaries:
        plot(b.x, b.y, daspect=[aspect, 1, 1], daspectratio="manual")
        hold("on")
    axis(plot_area)
    title("Specification of domain with %d boundaries" % len(boundaries))
    if marked_points:
        for pt, name in marked_points:
            text(pt[0], pt[1], name)
Example #22
0
def plot_boundaries(outer_boundary, inner_boundaries=[], marked_points=None):
    if not isinstance(inner_boundaries, (tuple, list)):
        inner_boundaries = [inner_boundaries]
    boundaries = [outer_boundary]
    boundaries.extend(inner_boundaries)

    # Find max/min of plotting area
    plot_area = [
        min([b.x.min() for b in boundaries]),
        max([b.x.max() for b in boundaries]),
        min([b.y.min() for b in boundaries]),
        max([b.y.max() for b in boundaries])
    ]

    aspect = (plot_area[3] - plot_area[2]) / (plot_area[1] - plot_area[0])
    for b in boundaries:
        plot(b.x, b.y, daspect=[aspect, 1, 1], daspectratio='manual')
        hold('on')
    axis(plot_area)
    title('Specification of domain with %d boundaries' % len(boundaries))
    if marked_points:
        for pt, name in marked_points:
            text(pt[0], pt[1], name)
Example #23
0
def run(gamma, beta=10, delta=40, scaling=1, animate=False):
    """Run the scaled model for welding."""
    if scaling == 1:
        v = gamma
        a = 1
    elif scaling == 2:
        v = 1
        a = 1.0/gamma

    b = 0.5*beta**2
    L = 1.0
    ymin = 0
    # Need gloal to be able change ymax in closure process_u
    global ymax
    ymax = 1.2

    I = lambda x: 0
    f = lambda x, t: delta*np.exp(-b*(x - v*t)**2)

    import time
    import scitools.std as plt
    plot_arrays = []

    def process_u(u, x, t, n):
        global ymax
        if animate:
            plt.plot(x, u, 'r-',
                     x, f(x, t[n])/delta, 'b-',
                     axis=[0, L, ymin, ymax], title='t=%f' % t[n],
                     xlabel='x', ylabel='u and f/%g' % delta)
        if t[n] == 0:
            time.sleep(1)
            plot_arrays.append(x)
        dt = t[1] - t[0]
        tol = dt/10.0
        if abs(t[n] - 0.2) < tol or abs(t[n] - 0.5) < tol:
            plot_arrays.append((u.copy(), f(x, t[n])/delta))
            if u.max() > ymax:
                ymax = u.max()

    Nx = 100
    D = 10
    T = 0.5
    u_L = u_R = 0
    theta = 1.0
    cpu = solver(
        I, a, f, L, Nx, D, T, theta, u_L, u_R, user_action=process_u)
    x = plot_arrays[0]
    plt.figure()
    for u, f in plot_arrays[1:]:
        plt.plot(x, u, 'r-', x, f, 'b--', axis=[x[0], x[-1], 0, ymax],
                 xlabel='$x$', ylabel=r'$u, \ f/%g$' % delta)
        plt.hold('on')
    plt.legend(['$u,\\ t=0.2$', '$f/%g,\\ t=0.2$' % delta,
                '$u,\\ t=0.5$', '$f/%g,\\ t=0.5$' % delta])
    filename = 'tmp1_gamma%g_s%d' % (gamma, scaling)
    s = 'diffusion' if scaling == 1 else 'source'
    plt.title(r'$\beta = %g,\ \gamma = %g,\ $' % (beta, gamma)
              + 'scaling=%s' % s)
    plt.savefig(filename + '.pdf');  plt.savefig(filename + '.png')
    return cpu
Example #24
0
 def plot(self):
     filename = 'logistic_' + str(self.problem) + '.pdf'
     plot(self.t, self.u)
     title(str(self.problem) + ', dt=%g' % self.dt)
     savefig(filename)
     show()
Example #25
0
def approximate(f,
                symbolic=False,
                d=1,
                N_e=4,
                numint=None,
                Omega=[0, 1],
                filename='tmp'):
    if symbolic:
        if numint == 'Trapezoidal':
            numint = [[sm.S(-1), sm.S(1)], [sm.S(1),
                                            sm.S(1)]]  # sympy integers
        elif numint == 'Simpson':
            numint = [[sm.S(-1), sm.S(0), sm.S(1)],
                      [
                          sm.Rational(1, 3),
                          sm.Rational(4, 3),
                          sm.Rational(1, 3)
                      ]]
        elif numint == 'Midpoint':
            numint = [[sm.S(0)], [sm.S(2)]]
        elif numint == 'GaussLegendre2':
            numint = [[-1 / sm.sqrt(3), 1 / sm.sqrt(3)], [sm.S(1), sm.S(1)]]
        elif numint == 'GaussLegendre3':
            numint = [[
                -sm.sqrt(sm.Rational(3, 5)), 0,
                sm.sqrt(sm.Rational(3, 5))
            ], [sm.Rational(5, 9),
                sm.Rational(8, 9),
                sm.Rational(5, 9)]]
        elif numint is not None:
            print 'Numerical rule %s is not supported' % numint
            numint = None
    else:
        if numint == 'Trapezoidal':
            numint = [[-1, 1], [1, 1]]
        elif numint == 'Simpson':
            numint = [[-1, 0, 1], [1. / 3, 4. / 3, 1. / 3]]
        elif numint == 'Midpoint':
            numint = [[0], [2]]
        elif numint == 'GaussLegendre2':
            numint = [[-1 / sqrt(3), 1 / sqrt(3)], [1, 1]]
        elif numint == 'GaussLegendre3':
            numint = [[-sqrt(3. / 5), 0, sqrt(3. / 5)],
                      [5. / 9, 8. / 9, 5. / 9]]
        elif numint is not None:
            print 'Numerical rule %s is not supported' % numint
            numint = None

    vertices, cells, dof_map = mesh_uniform(N_e, d, Omega, symbolic)

    # phi is a list where phi[e] holds the basis in cell no e
    # (this is required by assemble, which can work with
    # meshes with different types of elements).
    # len(dof_map[e]) is the number of nodes in cell e,
    # and the degree of the polynomial is len(dof_map[e])-1
    phi = [basis(len(dof_map[e]) - 1) for e in range(N_e)]

    print 'phi basis (reference element):\n', phi
    A, b = assemble(vertices,
                    cells,
                    dof_map,
                    phi,
                    f,
                    symbolic=symbolic,
                    numint=numint)

    print 'cells:', cells
    print 'vertices:', vertices
    print 'dof_map:', dof_map
    print 'A:\n', A
    print 'b:\n', b
    #print sm.latex(A, mode='plain')
    #print sm.latex(b, mode='plain')

    if symbolic:
        c = A.LUsolve(b)
    else:
        c = np.linalg.solve(A, b)

    print 'c:\n', c

    if not symbolic:
        print 'Plain interpolation/collocation:'
        x = sm.Symbol('x')
        f = sm.lambdify([x], f, modules='numpy')
        try:
            f_at_vertices = [f(xc) for xc in vertices]
            print f_at_vertices
        except Exception as e:
            print 'could not evaluate f numerically:'
            print e
    # else: nodes are symbolic so f(nodes[i]) only makes sense
    # in the non-symbolic case

    if not symbolic and filename is not None:
        title = 'P%d, N_e=%d' % (d, N_e)
        if numint is None:
            title += ', exact integration'
        else:
            title += ', integration: %s' % numint
        x_u, u = u_glob(np.asarray(c),
                        vertices,
                        cells,
                        dof_map,
                        resolution_per_element=51)
        x_f = np.linspace(Omega[0], Omega[1], 10001)  # mesh for f
        plt.plot(x_u, u, '-', x_f, f(x_f), '--')
        plt.legend(['u', 'f'])
        plt.title(title)
        plt.savefig(filename + '.pdf')
        plt.savefig(filename + '.png')
    return c
Example #26
0
def estimate(truncation_error, T, N_0, m, makeplot=True):
    """
    Compute the truncation error in a problem with one independent
    variable, using m meshes, and estimate the convergence
    rate of the truncation error.

    The user-supplied function truncation_error(dt, N) computes
    the truncation error on a uniform mesh with N intervals of
    length dt::

      R, t, R_a = truncation_error(dt, N)

    where R holds the truncation error at points in the array t,
    and R_a are the corresponding theoretical truncation error
    values (None if not available).

    The truncation_error function is run on a series of meshes
    with 2**i*N_0 intervals, i=0,1,...,m-1.
    The values of R and R_a are restricted to the coarsest mesh.
    and based on these data, the convergence rate of R (pointwise)
    and time-integrated R can be estimated empirically.
    """
    N = [2**i*N_0 for i in range(m)]

    R_I = np.zeros(m) # time-integrated R values on various meshes
    R   = [None]*m    # time series of R restricted to coarsest mesh
    R_a = [None]*m    # time series of R_a restricted to coarsest mesh
    dt = np.zeros(m)
    legends_R = [];  legends_R_a = []  # all legends of curves

    for i in range(m):
        dt[i] = T/float(N[i])
        R[i], t, R_a[i] = truncation_error(dt[i], N[i])

        R_I[i] = np.sqrt(dt[i]*np.sum(R[i]**2))

        if i == 0:
            t_coarse = t           # the coarsest mesh

        stride = N[i]/N_0
        R[i] = R[i][::stride]      # restrict to coarsest mesh
        R_a[i] = R_a[i][::stride]

        if makeplot:
            plt.figure(1)
            plt.plot(t_coarse, R[i], log='y')
            legends_R.append('N=%d' % N[i])
            plt.hold('on')

            plt.figure(2)
            plt.plot(t_coarse, R_a[i] - R[i], log='y')
            plt.hold('on')
            legends_R_a.append('N=%d' % N[i])

    if makeplot:
        plt.figure(1)
        plt.xlabel('time')
        plt.ylabel('pointwise truncation error')
        plt.legend(legends_R)
        plt.savefig('R_series.png')
        plt.savefig('R_series.pdf')
        plt.figure(2)
        plt.xlabel('time')
        plt.ylabel('pointwise error in estimated truncation error')
        plt.legend(legends_R_a)
        plt.savefig('R_error.png')
        plt.savefig('R_error.pdf')

    # Convergence rates
    r_R_I = convergence_rates(dt, R_I)
    print 'R integrated in time; r:',
    print ' '.join(['%.1f' % r for r in r_R_I])
    R = np.array(R)  # two-dim. numpy array
    r_R = [convergence_rates(dt, R[:,n])[-1]
           for n in range(len(t_coarse))]

    # Plot convergence rates
    if makeplot:
        plt.figure()
        plt.plot(t_coarse, r_R)
        plt.xlabel('time')
        plt.ylabel('r')
        plt.axis([t_coarse[0], t_coarse[-1], 0, 2.5])
        plt.title('Pointwise rate $r$ in truncation error $\sim\Delta t^r$')
        plt.savefig('R_rate_series.png')
        plt.savefig('R_rate_series.pdf')
Example #27
0
# -*- coding: utf-8 -*-
"""
Created on Mon Oct 19 21:13:30 2015

@author: antalcides
"""
from ForwardEuleruni import *
from LogisticUni import *

problem = Logistic(0.2, 1, 0.1)

T = 40
dt = 0.1
method = ForwardEuler(problem, dt)
method.set_initial_condition(problem.u0, 0)
u, t = method.solve(T)
from scitools.std import plot, hardcopy, xlabel, ylabel, title
plot(t, u)
xlabel('t')
ylabel('u')
title('Logistic growth: alpha=0.2, dt=%g, %d steps' \
    % (dt, len(u)-1))
def approximate(f, symbolic=False, d=1, N_e=4, numint=None,
                Omega=[0, 1], filename='tmp'):
    """
    Compute the finite element approximation, using Lagrange
    elements of degree d, to a symbolic expression f (with x
    as independent variable) on a domain Omega. N_e is the
    number of elements.
    symbolic=True implies symbolic expressions in the
    calculations, while symbolic=False means numerical
    computing.
    numint is the name of the numerical integration rule
    (Trapezoidal, Simpson, GaussLegendre2, GaussLegendre3,
    GaussLegendre4, etc.). numint=None implies exact
    integration.
    """
    numint_name = numint  # save name
    if symbolic:
        if numint == 'Trapezoidal':
            numint = [[sym.S(-1), sym.S(1)], [sym.S(1), sym.S(1)]]  # sympy integers
        elif numint == 'Simpson':
            numint = [[sym.S(-1), sym.S(0), sym.S(1)],
                      [sym.Rational(1,3), sym.Rational(4,3), sym.Rational(1,3)]]
        elif numint == 'Midpoint':
            numint = [[sym.S(0)],  [sym.S(2)]]
        elif numint == 'GaussLegendre2':
            numint = [[-1/sym.sqrt(3), 1/sym.sqrt(3)], [sym.S(1), sym.S(1)]]
        elif numint == 'GaussLegendre3':
            numint = [[-sym.sqrt(sym.Rational(3,5)), 0,
                       sym.sqrt(sym.Rational(3,5))],
                      [sym.Rational(5,9), sym.Rational(8,9),
                       sym.Rational(5,9)]]
        elif numint is not None:
            print 'Numerical rule %s is not supported for symbolic computing' % numint
            numint = None
    else:
        if numint == 'Trapezoidal':
            numint = [[-1, 1], [1, 1]]
        elif numint == 'Simpson':
            numint = [[-1, 0, 1], [1./3, 4./3, 1./3]]
        elif numint == 'Midpoint':
            numint = [[0], [2]]
        elif numint == 'GaussLegendre2':
            numint = [[-1/sqrt(3), 1/sqrt(3)], [1, 1]]
        elif numint == 'GaussLegendre3':
            numint = [[-sqrt(3./5), 0, sqrt(3./5)],
                      [5./9, 8./9, 5./9]]
        elif numint == 'GaussLegendre4':
            numint = [[-0.86113631, -0.33998104,  0.33998104,  0.86113631],
                      [ 0.34785485,  0.65214515,  0.65214515,  0.34785485]]
        elif numint == 'GaussLegendre5':
            numint = [[-0.90617985, -0.53846931, -0.        ,  0.53846931,  0.90617985],
                      [ 0.23692689,  0.47862867,  0.56888889,  0.47862867,  0.23692689]]
        elif numint is not None:
            print 'Numerical rule %s is not supported for numerical computing' % numint
            numint = None


    vertices, cells, dof_map = mesh_uniform(N_e, d, Omega, symbolic)

    # phi is a list where phi[e] holds the basis in cell no e
    # (this is required by assemble, which can work with
    # meshes with different types of elements).
    # len(dof_map[e]) is the number of nodes in cell e,
    # and the degree of the polynomial is len(dof_map[e])-1
    phi = [basis(len(dof_map[e])-1) for e in range(N_e)]

    print 'phi basis (reference element):\n', phi
    A, b = assemble(vertices, cells, dof_map, phi, f,
                    symbolic=symbolic, numint=numint)

    print 'cells:', cells
    print 'vertices:', vertices
    print 'dof_map:', dof_map
    print 'A:\n', A
    print 'b:\n', b
    #print sym.latex(A, mode='plain')
    #print sym.latex(b, mode='plain')

    if symbolic:
        c = A.LUsolve(b)
    else:
        c = np.linalg.solve(A, b)

    print 'c:\n', c

    if not symbolic:
        print 'Plain interpolation/collocation:'
        x = sym.Symbol('x')
        f = sym.lambdify([x], f, modules='numpy')
        try:
            f_at_vertices = [f(xc) for xc in vertices]
            print f_at_vertices
        except Exception as e:
            print 'could not evaluate f numerically:'
            print e
    # else: nodes are symbolic so f(nodes[i]) only makes sense
    # in the non-symbolic case

    if filename is not None:
        title = 'P%d, N_e=%d' % (d, N_e)
        if numint is None:
            title += ', exact integration'
        else:
            title += ', integration: %s' % numint_name
        x_u, u = u_glob(np.asarray(c), vertices, cells, dof_map,
                        resolution_per_element=51)
        x_f = np.linspace(Omega[0], Omega[1], 10001) # mesh for f
        import scitools.std as plt
        plt.plot(x_u, u, '-',
                 x_f, f(x_f), '--')
        plt.legend(['u', 'f'])
        plt.title(title)
        plt.savefig(filename + '.pdf')
        plt.savefig(filename + '.png')
    return c
Example #29
0
solvers = [
    odespy.RK2(f),
    odespy.RK3(f),
    odespy.RK4(f),
    # BackwardEuler must use Newton solver to converge
    # (Picard is default and leads to divergence)
    odespy.BackwardEuler(f, nonlinear_solver='Newton')
]

legends = []
for solver in solvers:
    solver.set_initial_condition(I)
    u, t = solver.solve(t_mesh)

    plt.plot(t, u)
    plt.hold('on')
    legends.append(solver.__class__.__name__)

# Compare with exact solution plotted on a very fine mesh
t_fine = np.linspace(0, T, 10001)
u_e = I * np.exp(-a * t_fine)
plt.plot(t_fine, u_e, '-')  # avoid markers by specifying line type
legends.append('exact')

plt.legend(legends)
plt.title('Time step: %g' % dt)
plt.savefig('odespy1_dt_%g.png' % dt)
plt.savefig('odespy1_dt_%g.pdf' % dt)
plt.show()
Example #30
0
def approximate(f, d, N_e, numint, Omega=[0, 1], filename='tmp'):
    """
    Compute the finite element approximation, using Lagrange
    elements of degree d, to a Python functionn f on a domain
    Omega. N_e is the number of elements.
    numint is the name of the numerical integration rule
    (Trapezoidal, Simpson, GaussLegendre2, GaussLegendre3,
    GaussLegendre4, etc.). numint=None implies exact
    integration.
    """
    from math import sqrt
    numint_name = numint  # save name
    if numint == 'Trapezoidal':
        numint = [[-1, 1], [1, 1]]
    elif numint == 'Simpson':
        numint = [[-1, 0, 1], [1. / 3, 4. / 3, 1. / 3]]
    elif numint == 'Midpoint':
        numint = [[0], [2]]
    elif numint == 'GaussLegendre2':
        numint = [[-1 / sqrt(3), 1 / sqrt(3)], [1, 1]]
    elif numint == 'GaussLegendre3':
        numint = [[-sqrt(3. / 5), 0, sqrt(3. / 5)], [5. / 9, 8. / 9, 5. / 9]]
    elif numint == 'GaussLegendre4':
        numint = [[-0.86113631, -0.33998104, 0.33998104, 0.86113631],
                  [0.34785485, 0.65214515, 0.65214515, 0.34785485]]
    elif numint == 'GaussLegendre5':
        numint = [[-0.90617985, -0.53846931, -0., 0.53846931, 0.90617985],
                  [0.23692689, 0.47862867, 0.56888889, 0.47862867, 0.23692689]]
    elif numint is not None:
        print 'Numerical rule %s is not supported '\
              'for numerical computing' % numint
        sys.exit(1)

    vertices, cells, dof_map = mesh_uniform(N_e, d, Omega)

    # phi is a list where phi[e] holds the basis in cell no e
    # (this is required by assemble, which can work with
    # meshes with different types of elements).
    # len(dof_map[e]) is the number of nodes in cell e,
    # and the degree of the polynomial is len(dof_map[e])-1
    phi = [basis(len(dof_map[e]) - 1) for e in range(N_e)]

    A, b = assemble(vertices, cells, dof_map, phi, f, numint=numint)

    print 'cells:', cells
    print 'vertices:', vertices
    print 'dof_map:', dof_map
    print 'A:\n', A
    print 'b:\n', b
    c = np.linalg.solve(A, b)
    print 'c:\n', c

    if filename is not None:
        title = 'P%d, N_e=%d' % (d, N_e)
        title += ', integration: %s' % numint_name
        x_u, u, _ = u_glob(np.asarray(c),
                           vertices,
                           cells,
                           dof_map,
                           resolution_per_element=51)
        x_f = np.linspace(Omega[0], Omega[1], 10001)  # mesh for f
        import scitools.std as plt
        plt.plot(x_u, u, '-', x_f, f(x_f), '--')
        plt.legend(['u', 'f'])
        plt.title(title)
        plt.savefig(filename + '.pdf')
        plt.savefig(filename + '.png')
    return c
def approximate(f, symbolic=False, d=1, N_e=4, numint=None,
                Omega=[0, 1], collocation=False, filename='tmp'):
    """
    Compute the finite element approximation, using Lagrange
    elements of degree d, to a symbolic expression f (with x
    as independent variable) on a domain Omega. N_e is the
    number of elements.
    symbolic=True implies symbolic expressions in the
    calculations, while symbolic=False means numerical
    computing.
    numint is the name of the numerical integration rule
    (Trapezoidal, Simpson, GaussLegendre2, GaussLegendre3,
    GaussLegendre4, etc.). numint=None implies exact
    integration.
    """
    numint_name = numint  # save name
    if symbolic:
        if numint == 'Trapezoidal':
            numint = [[sym.S(-1), sym.S(1)], [sym.S(1), sym.S(1)]]  # sympy integers
        elif numint == 'Simpson':
            numint = [[sym.S(-1), sym.S(0), sym.S(1)],
                      [sym.Rational(1,3), sym.Rational(4,3), sym.Rational(1,3)]]
        elif numint == 'Midpoint':
            numint = [[sym.S(0)],  [sym.S(2)]]
        elif numint == 'GaussLegendre2':
            numint = [[-1/sym.sqrt(3), 1/sym.sqrt(3)], [sym.S(1), sym.S(1)]]
        elif numint == 'GaussLegendre3':
            numint = [[-sym.sqrt(sym.Rational(3,5)), 0,
                       sym.sqrt(sym.Rational(3,5))],
                      [sym.Rational(5,9), sym.Rational(8,9),
                       sym.Rational(5,9)]]
        elif numint is not None:
            print 'Numerical rule %s is not supported for symbolic computing' % numint
            numint = None
    else:
        if numint == 'Trapezoidal':
            numint = [[-1, 1], [1, 1]]
        elif numint == 'Simpson':
            numint = [[-1, 0, 1], [1./3, 4./3, 1./3]]
        elif numint == 'Midpoint':
            numint = [[0], [2]]
        elif numint == 'GaussLegendre2':
            numint = [[-1/sqrt(3), 1/sqrt(3)], [1, 1]]
        elif numint == 'GaussLegendre3':
            numint = [[-sqrt(3./5), 0, sqrt(3./5)],
                      [5./9, 8./9, 5./9]]
        elif numint == 'GaussLegendre4':
            numint = [[-0.86113631, -0.33998104,  0.33998104,  0.86113631],
                      [ 0.34785485,  0.65214515,  0.65214515,  0.34785485]]
        elif numint == 'GaussLegendre5':
            numint = [[-0.90617985, -0.53846931, -0.        ,  0.53846931,  0.90617985],
                      [ 0.23692689,  0.47862867,  0.56888889,  0.47862867,  0.23692689]]
        elif numint is not None:
            print 'Numerical rule %s is not supported for numerical computing' % numint
            numint = None


    vertices, cells, dof_map = mesh_uniform(N_e, d, Omega, symbolic)

    # phi is a list where phi[e] holds the basis in cell no e
    # (this is required by assemble, which can work with
    # meshes with different types of elements).
    # len(dof_map[e]) is the number of nodes in cell e,
    # and the degree of the polynomial is len(dof_map[e])-1
    phi = [basis(len(dof_map[e])-1) for e in range(N_e)]

    A, b = assemble(vertices, cells, dof_map, phi, f,
                    symbolic=symbolic, numint=numint)

    print 'cells:', cells
    print 'vertices:', vertices
    print 'dof_map:', dof_map
    print 'A:\n', A
    print 'b:\n', b
    #print sym.latex(A, mode='plain')
    #print sym.latex(b, mode='plain')

    if symbolic:
        c = A.LUsolve(b)
        c = np.asarray([c[i,0] for i in range(c.shape[0])])
    else:
        c = np.linalg.solve(A, b)

    print 'c:\n', c

    x = sym.Symbol('x')
    f = sym.lambdify([x], f, modules='numpy')

    if collocation and not symbolic:
        print 'Plain interpolation/collocation:'
        # Should use vertices, but compute all nodes!
        f_at_vertices = [f(xc) for xc in vertices]
        print f_at_vertices

    if filename is not None:
        title = 'P%d, N_e=%d' % (d, N_e)
        if numint is None:
            title += ', exact integration'
        else:
            title += ', integration: %s' % numint_name
        x_u, u, _ = u_glob(c, vertices, cells, dof_map,
                           resolution_per_element=51)
        x_f = np.linspace(Omega[0], Omega[1], 10001) # mesh for f
        import scitools.std as plt
        plt.plot(x_u, u, '-',
                 x_f, f(x_f), '--')
        plt.legend(['u', 'f'])
        plt.title(title)
        plt.savefig(filename + '.pdf')
        plt.savefig(filename + '.png')

    return c
Example #32
0
def run_solvers_and_plot(solvers, timesteps_per_period=20,
                         num_periods=1, I=1, w=2*np.pi):
    P = 2*np.pi/w  # one period
    dt = P/timesteps_per_period
    N = num_periods*timesteps_per_period
    T = N*dt
    t_mesh = np.linspace(0, T, N+1)

    legends = []
    for solver in solvers:
        solver.set(f_kwargs={'w': w})
        solver.set_initial_condition([I, 0])
        u, t = solver.solve(t_mesh)

        # Make plots
        if num_periods <= 80:
            plt.figure(1)
            if len(t_mesh) <= 50:
                plt.plot(t, u[:,0])             # markers by default
            else:
                plt.plot(t, u[:,0], '-2')       # no markers
            plt.hold('on')
            legends.append(solver.__class__.__name__)
            plt.figure(2)
            if len(t_mesh) <= 50:
                plt.plot(u[:,0], u[:,1])        # markers by default
            else:
                plt.plot(u[:,0], u[:,1], '-2')  # no markers
            plt.hold('on')

        if num_periods > 20:
            minima, maxima = minmax(t, u[:,0])
            p = periods(maxima)
            a = amplitudes(minima, maxima)
            plt.figure(3)
            plt.plot(range(len(p)), 2*np.pi/p, '-')
            plt.hold('on')
            plt.figure(4)
            plt.plot(range(len(a)), a, '-')
            plt.hold('on')

    # Compare with exact solution plotted on a very fine mesh
    t_fine = np.linspace(0, T, 10001)
    u_e = I*np.cos(w*t_fine)
    v_e = -w*I*np.sin(w*t_fine)

    if num_periods < 80:
        plt.figure(1)
        plt.plot(t_fine, u_e, '-') # avoid markers by spec. line type
        legends.append('exact')
        plt.legend(legends, loc='upper left')
        plt.xlabel('t');  plt.ylabel('u')
        plt.title('Time step: %g' % dt)
        plt.savefig('vb_%d_%d_u.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_u.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_u.eps' % (timesteps_per_period, num_periods))

        plt.figure(2)
        plt.plot(u_e, v_e, '-') # avoid markers by spec. line type
        plt.legend(legends, loc='lower right')
        plt.xlabel('u(t)');  plt.ylabel('v(t)')
        plt.title('Time step: %g' % dt)
        plt.savefig('vb_%d_%d_pp.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_pp.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_pp.eps' % (timesteps_per_period, num_periods))
        del legends[-1]  # fig 3 and 4 does not have exact value

    if num_periods > 20:
        plt.figure(3)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated periods')
        plt.savefig('vb_%d_%d_p.eps' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_p.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_p.eps' % (timesteps_per_period, num_periods))
        plt.figure(4)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated amplitudes')
        plt.savefig('vb_%d_%d_a.eps' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_a.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_a.eps' % (timesteps_per_period, num_periods))
Example #33
0
def run(gamma, beta=10, delta=40, scaling=1, animate=False):
    """Run the scaled model for welding."""
    gamma = float(gamma)  # avoid integer division
    if scaling == 'a':
        v = gamma
        a = 1
        L = 1.0
        b = 0.5 * beta**2
    elif scaling == 'b':
        v = 1
        a = 1.0 / gamma
        L = 1.0
        b = 0.5 * beta**2
    elif scaling == 'c':
        v = 1
        a = beta / gamma
        L = beta
        b = 0.5
    elif scaling == 'd':
        # PDE: u_t = gamma**(-1)u_xx + gamma**(-1)*delta*f
        v = 1
        a = 1.0 / gamma
        L = 1.0
        b = 0.5 * beta**2
        delta *= 1.0 / gamma

    ymin = 0
    # Need global ymax to be able change ymax in closure process_u
    global ymax
    ymax = 1.2

    I = lambda x: 0
    f = lambda x, t: delta * np.exp(-b * (x - v * t)**2)

    import time
    import scitools.std as plt
    plot_arrays = []
    if scaling == 'c':
        plot_times = [0.2 * beta, 0.5 * beta]
    else:
        plot_times = [0.2, 0.5]

    def process_u(u, x, t, n):
        """
        Animate u, and store arrays in plot_arrays if
        t coincides with chosen times for plotting (plot_times).
        """
        global ymax
        if animate:
            plt.plot(x,
                     u,
                     'r-',
                     x,
                     f(x, t[n]) / delta,
                     'b-',
                     axis=[0, L, ymin, ymax],
                     title='t=%f' % t[n],
                     xlabel='x',
                     ylabel='u and f/%g' % delta)
        if t[n] == 0:
            time.sleep(1)
            plot_arrays.append(x)
        dt = t[1] - t[0]
        tol = dt / 10.0
        if abs(t[n] - plot_times[0]) < tol or \
           abs(t[n] - plot_times[1]) < tol:
            plot_arrays.append((u.copy(), f(x, t[n]) / delta))
            if u.max() > ymax:
                ymax = u.max()

    Nx = 100
    D = 10
    if scaling == 'c':
        T = 0.5 * beta
    else:
        T = 0.5
    u_L = u_R = 0
    theta = 1.0
    cpu = solver(I, a, f, L, Nx, D, T, theta, u_L, u_R, user_action=process_u)
    x = plot_arrays[0]
    plt.figure()
    for u, f in plot_arrays[1:]:
        plt.plot(x,
                 u,
                 'r-',
                 x,
                 f,
                 'b--',
                 axis=[x[0], x[-1], 0, ymax],
                 xlabel='$x$',
                 ylabel=r'$u, \ f/%g$' % delta)
        plt.hold('on')
    plt.legend([
        '$u,\\ t=%g$' % plot_times[0],
        '$f/%g,\\ t=%g$' % (delta, plot_times[0]),
        '$u,\\ t=%g$' % plot_times[1],
        '$f/%g,\\ t=%g$' % (delta, plot_times[1])
    ])
    filename = 'tmp1_gamma%g_%s' % (gamma, scaling)
    plt.title(r'$\beta = %g,\ \gamma = %g,\ $' % (beta, gamma) +
              'scaling=%s' % scaling)
    plt.savefig(filename + '.pdf')
    plt.savefig(filename + '.png')
    return cpu
Example #34
0
dt = float(sys.argv[1]) if len(sys.argv) >= 2 else 0.75
Nt = int(round(T/dt))
t_mesh = np.linspace(0, Nt*dt, Nt+1)

solvers = [odespy.RK2(f),
           odespy.RK3(f),
           odespy.RK4(f),
           # BackwardEuler must use Newton solver to converge
           odespy.BackwardEuler(f, nonlinear_solver='Newton')]

legends = []
for solver in solvers:
    solver.set_initial_condition(I)
    u, t = solver.solve(t_mesh)

    plt.plot(t, u)
    plt.hold('on')
    legends.append(solver.__class__.__name__)

# Compare with exact solution plotted on a very fine mesh
t_fine = np.linspace(0, T, 10001)
u_e = I*np.exp(-a*t_fine)
plt.plot(t_fine, u_e, '-') # avoid markers by specifying line type
legends.append('exact')

plt.legend(legends)
plt.title('Time step: %g' % dt)
plt.savefig('odespy1_dt_%g.png' % dt)
plt.savefig('odespy1_dt_%g.pdf' % dt)
plt.show()
Example #35
0
def approximate(f, symbolic=False, d=1, N_e=4, numint=None,
                Omega=[0, 1], filename='tmp'):
    if symbolic:
        if numint == 'Trapezoidal':
            numint = [[sp.S(-1), sp.S(1)], [sp.S(1), sp.S(1)]]  # sympy integers
        elif numint == 'Simpson':
            numint = [[sp.S(-1), sp.S(0), sp.S(1)],
                      [sp.Rational(1,3), sp.Rational(4,3), sp.Rational(1,3)]]
        elif numint == 'Midpoint':
            numint = [[sp.S(0)],  [sp.S(2)]]
        elif numint == 'GaussLegendre2':
            numint = [[-1/sp.sqrt(3), 1/sp.sqrt(3)], [sp.S(1), sp.S(1)]]
        elif numint == 'GaussLegendre3':
            numint = [[-sp.sqrt(sp.Rational(3,5)), 0,
                       sp.sqrt(sp.Rational(3,5))],
                      [sp.Rational(5,9), sp.Rational(8,9),
                       sp.Rational(5,9)]]
        elif numint is not None:
            print 'Numerical rule %s is not supported' % numint
            numint = None
    else:
        if numint == 'Trapezoidal':
            numint = [[-1, 1], [1, 1]]
        elif numint == 'Simpson':
            numint = [[-1, 0, 1], [1./3, 4./3, 1./3]]
        elif numint == 'Midpoint':
            numint = [[0], [2]]
        elif numint == 'GaussLegendre2':
            numint = [[-1/sqrt(3), 1/sqrt(3)], [1, 1]]
        elif numint == 'GaussLegendre3':
            numint = [[-sqrt(3./5), 0, sqrt(3./5)],
                      [5./9, 8./9, 5./9]]
        elif numint is not None:
            print 'Numerical rule %s is not supported' % numint
            numint = None


    vertices, cells, dof_map = mesh_uniform(N_e, d, Omega, symbolic)

    # phi is a list where phi[e] holds the basis in cell no e
    # (this is required by assemble, which can work with
    # meshes with different types of elements).
    # len(dof_map[e]) is the number of nodes in cell e,
    # and the degree of the polynomial is len(dof_map[e])-1
    phi = [basis(len(dof_map[e])-1) for e in range(N_e)]

    print 'phi basis (reference element):\n', phi
    A, b = assemble(vertices, cells, dof_map, phi, f,
                    symbolic=symbolic, numint=numint)

    print 'cells:', cells
    print 'vertices:', vertices
    print 'dof_map:', dof_map
    print 'A:\n', A
    print 'b:\n', b
    #print sp.latex(A, mode='plain')
    #print sp.latex(b, mode='plain')

    if symbolic:
        c = A.LUsolve(b)
    else:
        c = np.linalg.solve(A, b)

    print 'c:\n', c

    if not symbolic:
        print 'Plain interpolation/collocation:'
        x = sp.Symbol('x')
        f = sp.lambdify([x], f, modules='numpy')
        try:
            f_at_vertices = [f(xc) for xc in vertices]
            print f_at_vertices
        except Exception as e:
            print 'could not evaluate f numerically:'
            print e
    # else: nodes are symbolic so f(nodes[i]) only makes sense
    # in the non-symbolic case

    if not symbolic and filename is not None:
        title = 'P%d, N_e=%d' % (d, N_e)
        if numint is None:
            title += ', exact integration'
        else:
            title += ', integration: %s' % numint
        x_u, u = u_glob(np.asarray(c), vertices, cells, dof_map,
                        resolution_per_element=51)
        x_f = np.linspace(Omega[0], Omega[1], 10001) # mesh for f
        plt.plot(x_u, u, '-',
                 x_f, f(x_f), '--')
        plt.legend(['u', 'f'])
        plt.title(title)
        plt.savefig(filename + '.pdf')
        plt.savefig(filename + '.png')
    return c
Example #36
0
def approximate(f, d, N_e, numint, Omega=[0,1], filename='tmp'):
    """
    Compute the finite element approximation, using Lagrange
    elements of degree d, to a Python functionn f on a domain
    Omega. N_e is the number of elements.
    numint is the name of the numerical integration rule
    (Trapezoidal, Simpson, GaussLegendre2, GaussLegendre3,
    GaussLegendre4, etc.). numint=None implies exact
    integration.
    """
    from math import sqrt
    numint_name = numint  # save name
    if numint == 'Trapezoidal':
        numint = [[-1, 1], [1, 1]]
    elif numint == 'Simpson':
        numint = [[-1, 0, 1], [1./3, 4./3, 1./3]]
    elif numint == 'Midpoint':
        numint = [[0], [2]]
    elif numint == 'GaussLegendre2':
        numint = [[-1/sqrt(3), 1/sqrt(3)], [1, 1]]
    elif numint == 'GaussLegendre3':
        numint = [[-sqrt(3./5), 0, sqrt(3./5)],
                  [5./9, 8./9, 5./9]]
    elif numint == 'GaussLegendre4':
        numint = [[-0.86113631, -0.33998104,  0.33998104,
                   0.86113631],
                  [ 0.34785485,  0.65214515,  0.65214515,
                    0.34785485]]
    elif numint == 'GaussLegendre5':
        numint = [[-0.90617985, -0.53846931, -0.        ,
                   0.53846931,  0.90617985],
                  [ 0.23692689,  0.47862867,  0.56888889,
                    0.47862867,  0.23692689]]
    elif numint is not None:
        print 'Numerical rule %s is not supported for numerical computing' % numint
        sys.exit(1)


    vertices, cells, dof_map = mesh_uniform(N_e, d, Omega)

    # phi is a list where phi[e] holds the basis in cell no e
    # (this is required by assemble, which can work with
    # meshes with different types of elements).
    # len(dof_map[e]) is the number of nodes in cell e,
    # and the degree of the polynomial is len(dof_map[e])-1
    phi = [basis(len(dof_map[e])-1) for e in range(N_e)]

    A, b = assemble(vertices, cells, dof_map, phi, f,
                    numint=numint)

    print 'cells:', cells
    print 'vertices:', vertices
    print 'dof_map:', dof_map
    print 'A:\n', A
    print 'b:\n', b
    c = np.linalg.solve(A, b)
    print 'c:\n', c

    if filename is not None:
        title = 'P%d, N_e=%d' % (d, N_e)
        title += ', integration: %s' % numint_name
        x_u, u, _ = u_glob(np.asarray(c), vertices, cells, dof_map,
                           resolution_per_element=51)
        x_f = np.linspace(Omega[0], Omega[1], 10001) # mesh for f
        import scitools.std as plt
        plt.plot(x_u, u, '-',
                 x_f, f(x_f), '--')
        plt.legend(['u', 'f'])
        plt.title(title)
        plt.savefig(filename + '.pdf')
        plt.savefig(filename + '.png')
    return c
Example #37
0
def run(gamma, beta=10, delta=40, scaling=1, animate=False):
    """Run the scaled model for welding."""
    gamma = float(gamma)  # avoid integer division
    if scaling == 'a':
        v = gamma
        a = 1
        L = 1.0
        b = 0.5*beta**2
    elif scaling == 'b':
        v = 1
        a = 1.0/gamma
        L = 1.0
        b = 0.5*beta**2
    elif scaling == 'c':
        v = 1
        a = beta/gamma
        L = beta
        b = 0.5
    elif scaling == 'd':
        # PDE: u_t = gamma**(-1)u_xx + gamma**(-1)*delta*f
        v = 1
        a = 1.0/gamma
        L = 1.0
        b = 0.5*beta**2
        delta *= 1.0/gamma

    ymin = 0
    # Need global ymax to be able change ymax in closure process_u
    global ymax
    ymax = 1.2

    I = lambda x: 0
    f = lambda x, t: delta*np.exp(-b*(x - v*t)**2)

    import time
    import scitools.std as plt
    plot_arrays = []
    if scaling == 'c':
        plot_times = [0.2*beta, 0.5*beta]
    else:
        plot_times = [0.2, 0.5]

    def process_u(u, x, t, n):
        """
        Animate u, and store arrays in plot_arrays if
        t coincides with chosen times for plotting (plot_times).
        """
        global ymax
        if animate:
            plt.plot(x, u, 'r-',
                     x, f(x, t[n])/delta, 'b-',
                     axis=[0, L, ymin, ymax], title='t=%f' % t[n],
                     xlabel='x', ylabel='u and f/%g' % delta)
        if t[n] == 0:
            time.sleep(1)
            plot_arrays.append(x)
        dt = t[1] - t[0]
        tol = dt/10.0
        if abs(t[n] - plot_times[0]) < tol or \
           abs(t[n] - plot_times[1]) < tol:
            plot_arrays.append((u.copy(), f(x, t[n])/delta))
            if u.max() > ymax:
                ymax = u.max()

    Nx = 100
    D = 10
    if scaling == 'c':
        T = 0.5*beta
    else:
        T = 0.5
    u_L = u_R = 0
    theta = 1.0
    cpu = solver(
        I, a, f, L, Nx, D, T, theta, u_L, u_R, user_action=process_u)
    x = plot_arrays[0]
    plt.figure()
    for u, f in plot_arrays[1:]:
        plt.plot(x, u, 'r-', x, f, 'b--', axis=[x[0], x[-1], 0, ymax],
                 xlabel='$x$', ylabel=r'$u, \ f/%g$' % delta)
        plt.hold('on')
    plt.legend(['$u,\\ t=%g$' % plot_times[0],
                '$f/%g,\\ t=%g$' % (delta, plot_times[0]),
                '$u,\\ t=%g$' % plot_times[1],
                '$f/%g,\\ t=%g$' % (delta, plot_times[1])])
    filename = 'tmp1_gamma%g_%s' % (gamma, scaling)
    plt.title(r'$\beta = %g,\ \gamma = %g,\ $' % (beta, gamma)
              + 'scaling=%s' % scaling)
    plt.savefig(filename + '.pdf');  plt.savefig(filename + '.png')
    return cpu
 def plot(self):
     filename = 'logistic_' + str(self.problem) + '.pdf'
     plot(self.t, self.u)
     title(str(self.problem) + ', dt=%g' % self.dt)
     savefig(filename)
     show()
Example #39
0
def run_solvers_and_plot(solvers, timesteps_per_period=20,
                         num_periods=1, I=1, w=2*np.pi):
    P = 2*np.pi/w  # duration of one period
    dt = P/timesteps_per_period
    Nt = num_periods*timesteps_per_period
    T = Nt*dt
    t_mesh = np.linspace(0, T, Nt+1)

    legends = []
    for solver in solvers:
        solver.set(f_kwargs={'w': w})
        solver.set_initial_condition([I, 0])
        u, t = solver.solve(t_mesh)

        # Compute energy
        dt = t[1] - t[0]
        E = 0.5*((u[2:,0] - u[:-2,0])/(2*dt))**2 + 0.5*w**2*u[1:-1,0]**2
        # Compute error in energy
        E0 = 0.5*0**2 + 0.5*w**2*I**2
        e_E = E - E0

        solver_name = 'CrankNicolson' if solver.__class__.__name__ == \
                      'MidpointImplicit' else solver.__class__.__name__
        print '*** Relative max error in energy for %s [0,%g] with dt=%g: %.3E' % (solver_name, t[-1], dt, np.abs(e_E).max()/E0)

        # Make plots
        if num_periods <= 80:
            plt.figure(1)
            if len(t_mesh) <= 50:
                plt.plot(t, u[:,0])             # markers by default
            else:
                plt.plot(t, u[:,0], '-2')       # no markers
            plt.hold('on')
            legends.append(solver.__class__.__name__)
            plt.figure(2)
            if len(t_mesh) <= 50:
                plt.plot(u[:,0], u[:,1])        # markers by default
            else:
                plt.plot(u[:,0], u[:,1], '-2')  # no markers
            plt.hold('on')

        if num_periods > 20:
            minima, maxima = minmax(t, u[:,0])
            p = periods(maxima)
            a = amplitudes(minima, maxima)
            plt.figure(3)
            plt.plot(range(len(p)), 2*np.pi/p, '-')
            plt.hold('on')
            plt.figure(4)
            plt.plot(range(len(a)), a, '-')
            plt.hold('on')

    # Compare with exact solution plotted on a very fine mesh
    t_fine = np.linspace(0, T, 10001)
    u_e = I*np.cos(w*t_fine)
    v_e = -w*I*np.sin(w*t_fine)

    if num_periods < 80:
        plt.figure(1)
        plt.plot(t_fine, u_e, '-') # avoid markers by spec. line type
        legends.append('exact')
        plt.legend(legends, loc='upper left')
        plt.xlabel('t');  plt.ylabel('u')
        plt.title('Time step: %g' % dt)
        plt.savefig('vib_%d_%d_u.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.eps' % (timesteps_per_period, num_periods))

        plt.figure(2)
        plt.plot(u_e, v_e, '-') # avoid markers by spec. line type
        plt.legend(legends, loc='lower right')
        plt.xlabel('u(t)');  plt.ylabel('v(t)')
        plt.title('Time step: %g' % dt)
        plt.savefig('vib_%d_%d_pp.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_pp.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_pp.eps' % (timesteps_per_period, num_periods))
        del legends[-1]  # fig 3 and 4 does not have exact value

    if num_periods > 20:
        plt.figure(3)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated periods')
        plt.savefig('vib_%d_%d_p.eps' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_p.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_p.eps' % (timesteps_per_period, num_periods))
        plt.figure(4)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated amplitudes')
        plt.savefig('vib_%d_%d_a.eps' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_a.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_a.eps' % (timesteps_per_period, num_periods))
Example #40
0
def run_solvers_and_plot(solvers,
                         timesteps_per_period=20,
                         num_periods=1,
                         I=1,
                         w=2 * np.pi):
    P = 2 * np.pi / w  # one period
    dt = P / timesteps_per_period
    N = num_periods * timesteps_per_period
    T = N * dt
    t_mesh = np.linspace(0, T, N + 1)

    legends = []
    for solver in solvers:
        solver.set(f_kwargs={'w': w})
        solver.set_initial_condition([I, 0])
        u, t = solver.solve(t_mesh)

        # Make plots
        if num_periods <= 80:
            plt.figure(1)
            if len(t_mesh) <= 50:
                plt.plot(t, u[:, 0])  # markers by default
            else:
                plt.plot(t, u[:, 0], '-2')  # no markers
            plt.hold('on')
            legends.append(solver.__class__.__name__)
            plt.figure(2)
            if len(t_mesh) <= 50:
                plt.plot(u[:, 0], u[:, 1])  # markers by default
            else:
                plt.plot(u[:, 0], u[:, 1], '-2')  # no markers
            plt.hold('on')

        if num_periods > 20:
            minima, maxima = minmax(t, u[:, 0])
            p = periods(maxima)
            a = amplitudes(minima, maxima)
            plt.figure(3)
            plt.plot(range(len(p)), 2 * np.pi / p, '-')
            plt.hold('on')
            plt.figure(4)
            plt.plot(range(len(a)), a, '-')
            plt.hold('on')

    # Compare with exact solution plotted on a very fine mesh
    t_fine = np.linspace(0, T, 10001)
    u_e = I * np.cos(w * t_fine)
    v_e = -w * I * np.sin(w * t_fine)

    if num_periods < 80:
        plt.figure(1)
        plt.plot(t_fine, u_e, '-')  # avoid markers by spec. line type
        legends.append('exact')
        plt.legend(legends, loc='upper left')
        plt.xlabel('t')
        plt.ylabel('u')
        plt.title('Time step: %g' % dt)
        plt.savefig('vb_%d_%d_u.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_u.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_u.eps' % (timesteps_per_period, num_periods))

        plt.figure(2)
        plt.plot(u_e, v_e, '-')  # avoid markers by spec. line type
        plt.legend(legends, loc='lower right')
        plt.xlabel('u(t)')
        plt.ylabel('v(t)')
        plt.title('Time step: %g' % dt)
        plt.savefig('vb_%d_%d_pp.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_pp.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_pp.eps' % (timesteps_per_period, num_periods))
        del legends[-1]  # fig 3 and 4 does not have exact value

    if num_periods > 20:
        plt.figure(3)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated periods')
        plt.savefig('vb_%d_%d_p.eps' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_p.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_p.eps' % (timesteps_per_period, num_periods))
        plt.figure(4)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated amplitudes')
        plt.savefig('vb_%d_%d_a.eps' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_a.png' % (timesteps_per_period, num_periods))
        plt.savefig('vb_%d_%d_a.eps' % (timesteps_per_period, num_periods))
Example #41
0
def FTCS():
    """
        Forward time, centered space
    """
    L = 3.0
    Nx = 30
    bar = np.linspace(0, L, Nx+1)

    u0 = np.zeros(Nx+1)
    u1 = np.zeros(Nx+1)

    # IC is constant
    u0[0] = 5
    u0[-1] = 12
    u1[0] = 5
    u1[-1] = 12
    #u0[10] = 3

    k = 0.02364*np.ones(Nx+1)
    k[int(Nx*0.1):int(Nx)*0.5] = 0.02514
    
    rho = 1.292*np.ones(Nx+1)
    rho[int(Nx*0.1):int(Nx)*0.5] = 1.204

    cp = 1006*np.ones(Nx+1)
    cp[int(Nx*0.1):int(Nx)*0.5] = 1007

    alpha = 1.818*10**(-5)*np.ones(Nx+1)
    alpha[int(Nx*0.3):int(Nx)*0.5] = 3.243*10**(-5)


    alpha_max = max(alpha)#max(k) / (min(rho)*min(cp))

    r = 0.00001
    dx = L / Nx
    dt = r * dx**2 / alpha_max
    C = alpha_max*dt/dx**2    
    Nt = 2000000
    t = 0
    # constant conductivity
    """"
    for i in range(Nt):
        t += dt
        u1[1:-1] = u0[1:-1] + C * (u0[2::] - 2*u0[1:-1] + u0[0:-2]) 
        u0 = u1
        sci.plot(bar, u1)
        sci.title('t=%g'%t)
     """
    count = 0
    # non constant conductivity
    for i in range(Nt):
        count += 1
        #for i in range(1, Nx):
        #    u1[i] = u0[i] + dt/dx**2 * (k[i+1]*u0[i+1] - 2*k[i]*u0[i] + k[i-1]*u0[i-1]) / (rho[i]*cp[i])
        #u0 = u1
        t += dt
        u1[1:-1] =  u0[1:-1] + dt/dx**2 * (k[2::]*u0[2::] - 2*k[1:-1]*u0[1:-1] + k[0:-2]*u0[0:-2] ) / (rho[1:-1]*cp[1:-1])
        u0 = u1
        if count == 50000:
            sci.plot(bar, u1)
            sci.title('t=%g'%t)  
            count = 0      
Example #42
0
def approximate(f, symbolic=False, d=1, N_e=4, numint=None, Omega=[0, 1], filename="tmp"):
    if symbolic:
        if numint == "Trapezoidal":
            numint = [[sm.S(-1), sm.S(1)], [sm.S(1), sm.S(1)]]  # sympy integers
        elif numint == "Simpson":
            numint = [[sm.S(-1), sm.S(0), sm.S(1)], [sm.Rational(1, 3), sm.Rational(4, 3), sm.Rational(1, 3)]]
        elif numint == "Midpoint":
            numint = [[sm.S(0)], [sm.S(2)]]
        elif numint == "GaussLegendre2":
            numint = [[-1 / sm.sqrt(3), 1 / sm.sqrt(3)], [sm.S(1), sm.S(1)]]
        elif numint == "GaussLegendre3":
            numint = [
                [-sm.sqrt(sm.Rational(3, 5)), 0, sm.sqrt(sm.Rational(3, 5))],
                [sm.Rational(5, 9), sm.Rational(8, 9), sm.Rational(5, 9)],
            ]
        elif numint is not None:
            print "Numerical rule %s is not supported" % numint
            numint = None
    else:
        if numint == "Trapezoidal":
            numint = [[-1, 1], [1, 1]]
        elif numint == "Simpson":
            numint = [[-1, 0, 1], [1.0 / 3, 4.0 / 3, 1.0 / 3]]
        elif numint == "Midpoint":
            numint = [[0], [2]]
        elif numint == "GaussLegendre2":
            numint = [[-1 / sqrt(3), 1 / sqrt(3)], [1, 1]]
        elif numint == "GaussLegendre3":
            numint = [[-sqrt(3.0 / 5), 0, sqrt(3.0 / 5)], [5.0 / 9, 8.0 / 9, 5.0 / 9]]
        elif numint is not None:
            print "Numerical rule %s is not supported" % numint
            numint = None

    vertices, cells, dof_map = mesh_uniform(N_e, d, Omega, symbolic)

    # phi is a list where phi[e] holds the basis in cell no e
    # (this is required by assemble, which can work with
    # meshes with different types of elements).
    # len(dof_map[e]) is the number of nodes in cell e,
    # and the degree of the polynomial is len(dof_map[e])-1
    phi = [basis(len(dof_map[e]) - 1) for e in range(N_e)]

    print "phi basis (reference element):\n", phi
    A, b = assemble(vertices, cells, dof_map, phi, f, symbolic=symbolic, numint=numint)

    print "cells:", cells
    print "vertices:", vertices
    print "dof_map:", dof_map
    print "A:\n", A
    print "b:\n", b
    # print sm.latex(A, mode='plain')
    # print sm.latex(b, mode='plain')

    if symbolic:
        c = A.LUsolve(b)
    else:
        c = np.linalg.solve(A, b)

    print "c:\n", c

    if not symbolic:
        print "Plain interpolation/collocation:"
        x = sm.Symbol("x")
        f = sm.lambdify([x], f, modules="numpy")
        try:
            f_at_vertices = [f(xc) for xc in vertices]
            print f_at_vertices
        except Exception as e:
            print "could not evaluate f numerically:"
            print e
    # else: nodes are symbolic so f(nodes[i]) only makes sense
    # in the non-symbolic case

    if not symbolic and filename is not None:
        title = "P%d, N_e=%d" % (d, N_e)
        if numint is None:
            title += ", exact integration"
        else:
            title += ", integration: %s" % numint
        x_u, u = u_glob(np.asarray(c), vertices, cells, dof_map, resolution_per_element=51)
        x_f = np.linspace(Omega[0], Omega[1], 10001)  # mesh for f
        plt.plot(x_u, u, "-", x_f, f(x_f), "--")
        plt.legend(["u", "f"])
        plt.title(title)
        plt.savefig(filename + ".pdf")
        plt.savefig(filename + ".png")
    return c
Example #43
0
"""
As uniform_numbers1.py but the histogram is plotted both as a piecewise
constant curve and a piecewise linear curve. The number of bins is
read from the command line.
"""
import sys
N = int(sys.argv[1])
nbins = int(sys.argv[2])

import numpy as np
np.random.seed(12)
# Vectorized generation of random numbers
samples = np.random.random(size=N)

import scitools.std as st
x1, y1 = st.compute_histogram(samples, nbins, piecewise_constant=True)
x2, y2 = st.compute_histogram(samples, nbins, piecewise_constant=False)
st.plot(x1, y1, 'r', x2, y2, 'b')
st.title('%d samples of uniform numbers on (0,1)' % N)
st.hardcopy('tmp.eps')


Example #44
0
def run(gamma, beta=10, delta=40, scaling=1, animate=False):
    """Run the scaled model for welding."""
    if scaling == 1:
        v = gamma
        a = 1
    elif scaling == 2:
        v = 1
        a = 1.0 / gamma

    b = 0.5 * beta**2
    L = 1.0
    ymin = 0
    # Need gloal to be able change ymax in closure process_u
    global ymax
    ymax = 1.2

    I = lambda x: 0
    f = lambda x, t: delta * np.exp(-b * (x - v * t)**2)

    import time
    import scitools.std as plt
    plot_arrays = []

    def process_u(u, x, t, n):
        global ymax
        if animate:
            plt.plot(x,
                     u,
                     'r-',
                     x,
                     f(x, t[n]) / delta,
                     'b-',
                     axis=[0, L, ymin, ymax],
                     title='t=%f' % t[n],
                     xlabel='x',
                     ylabel='u and f/%g' % delta)
        if t[n] == 0:
            time.sleep(1)
            plot_arrays.append(x)
        dt = t[1] - t[0]
        tol = dt / 10.0
        if abs(t[n] - 0.2) < tol or abs(t[n] - 0.5) < tol:
            plot_arrays.append((u.copy(), f(x, t[n]) / delta))
            if u.max() > ymax:
                ymax = u.max()

    Nx = 100
    D = 10
    T = 0.5
    u_L = u_R = 0
    theta = 1.0
    cpu = solver(I, a, f, L, Nx, D, T, theta, u_L, u_R, user_action=process_u)
    x = plot_arrays[0]
    plt.figure()
    for u, f in plot_arrays[1:]:
        plt.plot(x,
                 u,
                 'r-',
                 x,
                 f,
                 'b--',
                 axis=[x[0], x[-1], 0, ymax],
                 xlabel='$x$',
                 ylabel=r'$u, \ f/%g$' % delta)
        plt.hold('on')
    plt.legend([
        '$u,\\ t=0.2$',
        '$f/%g,\\ t=0.2$' % delta, '$u,\\ t=0.5$',
        '$f/%g,\\ t=0.5$' % delta
    ])
    filename = 'tmp1_gamma%g_s%d' % (gamma, scaling)
    s = 'diffusion' if scaling == 1 else 'source'
    plt.title(r'$\beta = %g,\ \gamma = %g,\ $' % (beta, gamma) +
              'scaling=%s' % s)
    plt.savefig(filename + '.pdf')
    plt.savefig(filename + '.png')
    return cpu
def run_solvers_and_plot(solvers,
                         timesteps_per_period=20,
                         num_periods=1,
                         I=1,
                         w=2 * np.pi):
    P = 2 * np.pi / w  # duration of one period
    dt = P / timesteps_per_period
    Nt = num_periods * timesteps_per_period
    T = Nt * dt
    t_mesh = np.linspace(0, T, Nt + 1)

    legends = []
    for solver in solvers:
        solver.set(f_kwargs={'w': w})
        solver.set_initial_condition([I, 0])
        u, t = solver.solve(t_mesh)

        # Compute energy
        dt = t[1] - t[0]
        E = 0.5 * ((u[2:, 0] - u[:-2, 0]) /
                   (2 * dt))**2 + 0.5 * w**2 * u[1:-1, 0]**2
        # Compute error in energy
        E0 = 0.5 * 0**2 + 0.5 * w**2 * I**2
        e_E = E - E0

        solver_name = 'CrankNicolson' if solver.__class__.__name__ == \
                      'MidpointImplicit' else solver.__class__.__name__
        print '*** Relative max error in energy for %s [0,%g] with dt=%g: %.3E' % (
            solver_name, t[-1], dt, np.abs(e_E).max() / E0)

        # Make plots
        if num_periods <= 80:
            plt.figure(1)
            if len(t_mesh) <= 50:
                plt.plot(t, u[:, 0])  # markers by default
            else:
                plt.plot(t, u[:, 0], '-2')  # no markers
            plt.hold('on')
            legends.append(solver_name)
            plt.figure(2)
            if len(t_mesh) <= 50:
                plt.plot(u[:, 0], u[:, 1])  # markers by default
            else:
                plt.plot(u[:, 0], u[:, 1], '-2')  # no markers
            plt.hold('on')

        if num_periods > 20:
            minima, maxima = minmax(t, u[:, 0])
            p = periods(maxima)
            a = amplitudes(minima, maxima)
            plt.figure(3)
            plt.plot(range(len(p)), 2 * np.pi / p, '-')
            plt.hold('on')
            plt.figure(4)
            plt.plot(range(len(a)), a, '-')
            plt.hold('on')

    # Compare with exact solution plotted on a very fine mesh
    t_fine = np.linspace(0, T, 10001)
    u_e = I * np.cos(w * t_fine)
    v_e = -w * I * np.sin(w * t_fine)

    if num_periods < 80:
        plt.figure(1)
        plt.plot(t_fine, u_e, '-')  # avoid markers by spec. line type
        legends.append('exact')
        plt.legend(legends, loc='upper left')
        plt.xlabel('t')
        plt.ylabel('u')
        plt.title('Time step: %g' % dt)
        plt.savefig('vib_%d_%d_u.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_u.pdf' % (timesteps_per_period, num_periods))

        plt.figure(2)
        plt.plot(u_e, v_e, '-')  # avoid markers by spec. line type
        plt.legend(legends, loc='lower right')
        plt.xlabel('u(t)')
        plt.ylabel('v(t)')
        plt.title('Time step: %g' % dt)
        plt.savefig('vib_%d_%d_pp.png' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_pp.pdf' % (timesteps_per_period, num_periods))
        del legends[-1]  # fig 3 and 4 does not have exact value

    if num_periods > 20:
        plt.figure(3)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated periods')
        plt.savefig('vib_%d_%d_p.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_p.png' % (timesteps_per_period, num_periods))
        plt.figure(4)
        plt.legend(legends, loc='center right')
        plt.title('Empirically estimated amplitudes')
        plt.savefig('vib_%d_%d_a.pdf' % (timesteps_per_period, num_periods))
        plt.savefig('vib_%d_%d_a.png' % (timesteps_per_period, num_periods))