(in-package :clf)

(defun set-constant-field-2d (grid pv)
  "Задаёт в сетке `grid' постоянное поле"
  (loop for i from 0 to (cells-max-x grid) do
       (loop for j from 0 to (cells-max-y grid) do
	    (setf (cell grid (index i j))
		  (primitive->conservative pv)))))

(defun set-monotonous-field-2d-x (grid &key left-vars right-vars)
  "Задаёт в сетке `grid' поле, линейно изменяющееся от `left-vars' до `right-vars'"
  (let ((pv-grad (pvar/ (pvar- right-vars left-vars)
			 (cells-amount-x grid))))
     (loop for i from 0 to (cells-max-x grid) do
	  (let ((pv (pvar+ left-vars
			   (pvar* (+ i 0.5) pv-grad))))
	    (loop for j from 0 to (cells-max-y grid) do
	       (setf (cell grid (index i j))
		     (primitive->conservative pv)))))))

(defun set-splitted-field-2d-x (grid &key left-vars right-vars)
  "Задаёт в сетке `grid' поле, до половины заполненное `left-vars', а после - `right-vars'"
  (format t "Задаём поле, разделённое по оси x~%")
  (format t "Колонки: ~T") (print-headers t left-vars) (newline)
  (format t "left:~T") (print-content t left-vars :with-headers nil) (newline)
  (format t "right:~T") (print-content t right-vars :with-headers nil) (newline)
  (let* ((mid-x-index (round (/ (cells-amount-x grid) 2)))
	 (left-vars (primitive->conservative left-vars))
	 (right-vars (primitive->conservative right-vars)))
    (loop for i from 0 to (cells-max-x grid) do
	 (loop for j from 0 to (cells-max-y grid) do
	      (setf (cell grid (index i j))
		    (if (< i mid-x-index)
			left-vars
			right-vars))))))

(defun perturbate-field-x (grid perturbate)
  "Эта функция применяет к каждой ячейке сетки `grid' с установленным
полем функцию `perturbate', которая вызывается с индексом по x текущей
ячейки. Параметры этой ячейки в сетке домножаются на полученный
коэффициент."
  (let* ((cells-amount-x (cells-amount-x grid))
	 (cells-amount-y (cells-amount-y grid))
	 (cells-max-x (1- cells-amount-x))
	 (cells-max-y (1- cells-amount-y)))
    (loop for i from 0 to cells-max-x do
	 (loop for j from 0 to cells-max-y do
	      (let* ((pv (conservative->primitive (cell grid (index i j))))
		     (pv (pvar* pv (funcall perturbate i))))
		(setf (var-vector (cell grid (index i j)))
		      (var-vector (primitive->conservative pv))))))))