from typing import Optional

import numpy as np

import consts
from util import Grid


#@cachier(stale_after=datetime.timedelta(hours=1))
def solve_explicit(grid: Grid) -> Optional[np.ndarray]:
  if grid.gamma > 1 / 2:
    return None

  ug = np.zeros((grid.K + 1, grid.I + 1), dtype=float)

  ug[0, :] = np.sin(np.pi * grid.xs / consts.l) ** 2 * 4 / 10

  for k in range(1, grid.K + 1):
    # middle
    ug[k, 1: grid.I] = (
        grid.gamma * ug[k - 1, 0: grid.I - 1] +
        (-2 * grid.gamma + 1) * ug[k - 1, 1: grid.I] +
        grid.gamma * ug[k - 1, 2: grid.I + 1]
    )

    # left
    ug[k, 0] = ug[k, 1] / (consts.H * grid.h_x + 1)

    # right
    ug[k, grid.I] = ug[k, grid.I - 1] / (consts.H * grid.h_x + 1)

  return ug
