Skip to content
evolve.pyx 2.94 KiB
Newer Older
# cython: profile=True

import numpy as np
cimport numpy as cnp

import cython

# Time evolution for the inner part of the grid
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
cpdef evolve_inner(cnp.ndarray[cnp.double_t, ndim=2]u,
           cnp.ndarray[cnp.double_t, ndim=2]u_previous,
           double a, double dt, double dx2, double dy2):
    """Explicit time evolution.
       u:            new temperature field
       u_previous:   previous field
       a:            diffusion constant
       dt:           time step. """

    cdef int nx = u.shape[0] - 2
    cdef int ny = u.shape[1] - 2

    cdef int i,j

    # Multiplication is more efficient than division
    cdef double dx2inv = 1. / dx2
    cdef double dy2inv = 1. / dy2

    for i in range(2, nx):
        for j in range(2, ny):
            u[i, j] = u_previous[i, j] + a * dt * ( \
             (u_previous[i+1, j] - 2*u_previous[i, j] + \
              u_previous[i-1, j]) * dx2inv + \
             (u_previous[i, j+1] - 2*u_previous[i, j] + \
                 u_previous[i, j-1]) * dy2inv )

# Time evolution for the edges  of the grid
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
cpdef evolve_edges(cnp.ndarray[cnp.double_t, ndim=2]u,
           cnp.ndarray[cnp.double_t, ndim=2]u_previous,
           double a, double dt, double dx2, double dy2):
    """Explicit time evolution.
       u:            new temperature field
       u_previous:   previous field
       a:            diffusion constant
       dt:           time step
       dx2:          grid spacing squared, i.e. dx^2
       dy2:            -- "" --          , i.e. dy^2"""

    cdef int nx = u.shape[0] - 2
    cdef int ny = u.shape[1] - 2

    cdef int i,j

    # Multiplication is more efficient than division
    cdef double dx2inv = 1. / dx2
    cdef double dy2inv = 1. / dy2

    j = 1
    for i in range(1, nx+1):
        u[i, j] = u_previous[i, j] + a * dt * ( \
         (u_previous[i+1, j] - 2*u_previous[i, j] + \
          u_previous[i-1, j]) * dx2inv + \
         (u_previous[i, j+1] - 2*u_previous[i, j] + \
          u_previous[i, j-1]) * dy2inv )

    j = ny
    for i in range(1, nx+1):
        u[i, j] = u_previous[i, j] + a * dt * ( \
         (u_previous[i+1, j] - 2*u_previous[i, j] + \
          u_previous[i-1, j]) * dx2inv + \
         (u_previous[i, j+1] - 2*u_previous[i, j] + \
          u_previous[i, j-1]) * dy2inv )

    i = 1
    for j in range(1, ny+1):
        u[i, j] = u_previous[i, j] + a * dt * ( \
         (u_previous[i+1, j] - 2*u_previous[i, j] + \
          u_previous[i-1, j]) * dx2inv + \
         (u_previous[i, j+1] - 2*u_previous[i, j] + \
          u_previous[i, j-1]) * dy2inv )

    i = nx
    for j in range(1, ny+1):
        u[i, j] = u_previous[i, j] + a * dt * ( \
         (u_previous[i+1, j] - 2*u_previous[i, j] + \
          u_previous[i-1, j]) * dx2inv + \
         (u_previous[i, j+1] - 2*u_previous[i, j] + \
          u_previous[i, j-1]) * dy2inv )