(in-package :clf)

(defun test-kt-constant (&key (cells-nx 4) (cells-ny 1) (cu 1) (output-dir #P"~/prog/clfpv/test-kt-constant/"))
  "Тест на постоянном поле. Он нужен в основном для того, чтобы
проверить консервативность схемы, а также для дебага программы."
  (ensure-directories-exist output-dir)
  (let ((*DEFAULT-PATHNAME-DEFAULTS* output-dir))
    (let ((grid (make-instance 'grid2d-cv
			       :cells-amount-x cells-nx
			       :cells-amount-y cells-ny
			       :left-boundary-condition 'zeroe
			       :right-boundary-condition 'zeroe
			       :bottom-boundary-condition 'zeroe
			       :top-boundary-condition 'zeroe)))
      (gridbg "1" grid)
      (init-grid grid
		 :left-border-coord 0.0d0
		 :right-border-coord 1.0d0
		 :top-border-line (constant-function 1.0d0)
		 :bottom-border-line (constant-function 0.0d0)
		 :thickening-coef-x 1
		 :thickening-coef-y 1)
      (gridbg "2" grid)
      (set-constant-field-2d grid
			     (make-instance 'conservative-variables
					    :phi 0.999999d0
					    :P 100000.0d0
					    :ug 25.0d0
					    :ul 25.0d0))
      (gridbg "3" grid)
      (update-boundary-cells grid)
      (gridbg "4" grid)
      (gridbg "start-grid" grid)
      (let ((newgrid (march grid
			    :finish-step 10
			    :output-every-step 1
			    :cu cu
			    )))
	(gridbg "final-grid" newgrid)
	newgrid
	))))

(defun test-kt-split-1 (&key (cells-nx 100) (cells-ny 1) (cu 0.001) (output-dir #P"~/prog/clfpv/test-kt-split-1/"))
  "Тест на стоячем скачке уплотнения. В данном тесте значение phi
близко к 1, а это значит, что решение должно быть почти таким же, как
в газе."
  (ensure-directories-exist output-dir)
  (let ((*DEFAULT-PATHNAME-DEFAULTS* output-dir))
    (let ((grid (make-instance 'grid2d-cv
			       :cells-amount-x cells-nx
			       :cells-amount-y cells-ny
			       :left-boundary-condition 'zeroe
			       :right-boundary-condition 'zeroe
			       :bottom-boundary-condition 'zeroe
			       :top-boundary-condition 'zeroe)))
      (gridbg "1 (instance)" grid)
      (init-grid grid
		 :left-border-coord 0.0d0
		 :right-border-coord 1.0d0
		 :top-border-line (constant-function 1.0d0)
		 :bottom-border-line (constant-function 0.0d0)
		 :thickening-coef-x 1
		 :thickening-coef-y 1)
      (gridbg "2 (init-grid)" grid)
      (let* ((left-vars (make-instance 'primitive-variables
				       :phi 0.999999
				       :rg 1.0
				       :ug 400.0
				       :ul 400.0))
	     (right-vars (make-instance 'primitive-variables
					:phi (phi left-vars)
					:ug (/ (* *sos* *sos*)
					       (* *kappa* (ug left-vars)))
					:ul (/ (* *sos* *sos*)
					       (* *kappa* (ul left-vars)))
					:rg (/ (* (rg left-vars) (ug left-vars))
					       ;; на ug справа
					       (/ (* *sos* *sos*)
						  (* *kappa* (ug left-vars)))))))
	(set-splitted-field-2d-x grid
				 :left-vars left-vars
				 :right-vars right-vars))
      (gridbg "3 (set-field)" grid)
      (update-boundary-cells grid)
      (gridbg "4 (boundaries)" grid)
      (gridbg "start-grid" grid)
      (let ((newgrid (march grid
			    :finish-time 0.005
			    :output-every-time 0.0001
			    :cu cu
			    )))
	(gridbg "final-grid" newgrid)
	newgrid
	)
      )))

(defun test-kt-split-1/convergence (&key (cells-nx 100) (cells-ny 1) (cu 0.001)
				      (output-dir #P"~/prog/clfpv/test-kt-split-1-convergence/"))
  "Тест на стоячем скачке уплотнения. В данном тесте значение phi
близко к 1, а это значит, что решение должно быть почти таким же, как
в газе. Отличие от test-kt-split-1 заключается в том, что здесь я
тестирую остановку по невязке."
  (ensure-directories-exist output-dir)
  (let ((*DEFAULT-PATHNAME-DEFAULTS* output-dir))
    (let ((grid (make-instance 'grid2d-cv
			       :cells-amount-x cells-nx
			       :cells-amount-y cells-ny
			       :left-boundary-condition 'zeroe
			       :right-boundary-condition 'zeroe
			       :bottom-boundary-condition 'zeroe
			       :top-boundary-condition 'zeroe)))
      (gridbg "1 (instance)" grid)
      (init-grid grid
		 :left-border-coord 0.0d0
		 :right-border-coord 1.0d0
		 :top-border-line (constant-function 1.0d0)
		 :bottom-border-line (constant-function 0.0d0)
		 :thickening-coef-x 1
		 :thickening-coef-y 1)
      (gridbg "2 (init-grid)" grid)
      (let* ((left-vars (make-instance 'primitive-variables
				       :phi 0.999999
				       :rg 1.0
				       :ug 400.0
				       :ul 400.0))
	     (right-vars (make-instance 'primitive-variables
					:phi (phi left-vars)
					:ug (/ (* *sos* *sos*)
					       (* *kappa* (ug left-vars)))
					:ul (/ (* *sos* *sos*)
					       (* *kappa* (ul left-vars)))
					:rg (/ (* (rg left-vars) (ug left-vars))
					       ;; на ug справа
					       (/ (* *sos* *sos*)
						  (* *kappa* (ug left-vars)))))))
	(set-splitted-field-2d-x grid
				 :left-vars left-vars
				 :right-vars right-vars))
      (gridbg "3 (set-field)" grid)
      (update-boundary-cells grid)
      (gridbg "4 (boundaries)" grid)
      (gridbg "start-grid" grid)
      (let ((newgrid (march grid
			    :finish-time 0.005
			    :finish-convergence 1.0d-6
			    :output-every-time 0.0001
			    :cu cu
			    )))
	(gridbg "final-grid" newgrid)
	newgrid
	)
      )))

(defun test-kt-split-1v2 (&key (cells-nx 100) (cells-ny 1) (cu 0.001) (output-dir #P"~/prog/clfpv/test-kt-split-1v2/"))
  "Тест на стоячем скачке уплотнения. В данном тесте значение phi
близко к 1, а это значит, что решение должно быть почти таким же, как
в газе. Этот тест отличается от предыдущего тем, что во всей сетке
скорости увеличены, чтобы скачок двигался. Таким образом можно
наблюдать размазывание."
  (ensure-directories-exist output-dir)
  (let ((*DEFAULT-PATHNAME-DEFAULTS* output-dir))
    (let ((grid (make-instance 'grid2d-cv
			       :cells-amount-x cells-nx
			       :cells-amount-y cells-ny
			       :left-boundary-condition 'zeroe
			       :right-boundary-condition 'zeroe
			       :bottom-boundary-condition 'zeroe
			       :top-boundary-condition 'zeroe)))
      (gridbg "1 (instance)" grid)
      (init-grid grid
		 :left-border-coord 0.0d0
		 :right-border-coord 1.0d0
		 :top-border-line (constant-function 1.0d0)
		 :bottom-border-line (constant-function 0.0d0)
		 :thickening-coef-x 1
		 :thickening-coef-y 1)
      (gridbg "2 (init-grid)" grid)
      (let* ((left-vars (make-instance 'primitive-variables
				       :phi 0.999999
				       :rg 1.0
				       :ug 400.0
				       :ul 400.0))
	     (right-vars (make-instance 'primitive-variables
					:phi (phi left-vars)
					:ug (/ (* *sos* *sos*)
					       (* *kappa* (ug left-vars)))
					:ul (/ (* *sos* *sos*)
					       (* *kappa* (ul left-vars)))
					:rg (/ (* (rg left-vars) (ug left-vars))
					       ;; на ug справа
					       (/ (* *sos* *sos*)
						  (* *kappa* (ug left-vars)))))))
	(set-splitted-field-2d-x grid
				 :left-vars left-vars
				 :right-vars right-vars))
      (loop for i from (min-x-index grid) to (max-x-index grid) do
	   (loop for j from (min-y-index grid) to (min-y-index grid) do
		(let ((pv (conservative->primitive (cell grid (index i j)))))
		  (incf (ug pv) 500)
		  (incf (ul pv) 500)
		  (setf (cell grid (index i j)) (primitive->conservative pv)))))
      (format t "~%INCREMENT DEBUG:~%")
      (print-content t (cell grid (index 0 0)))
      
      (gridbg "3 (set-field)" grid)
      (update-boundary-cells grid)
      (gridbg "4 (boundaries)" grid)
      (gridbg "start-grid" grid)
      (let ((newgrid (march grid
			    :finish-step 100
			    :output-every-step 1
			    :cu cu
			    )))
	(gridbg "final-grid" newgrid)
	newgrid
	)
      )))

(defun test-kt-split-2 (&key (cells-nx 100) (cells-ny 1) (cu 0.001) (output-dir #P"~/prog/clfpv/test-kt-split-2/"))
  "Тест на стоячем скачке уплотнения при phi = 0.9. Этот тест нужен,
чтобы проверить, как ведёт себя метод при расчёте не чисто газового
течения."
  (ensure-directories-exist output-dir)
  (let ((*DEFAULT-PATHNAME-DEFAULTS* output-dir))
    (let ((grid (make-instance 'grid2d-cv
			       :cells-amount-x cells-nx
			       :cells-amount-y cells-ny
			       :left-boundary-condition 'zeroe
			       :right-boundary-condition 'zeroe
			       :bottom-boundary-condition 'zeroe
			       :top-boundary-condition 'zeroe)))
      (gridbg "1 (instance)" grid)
      (init-grid grid
		 :left-border-coord 0.0d0
		 :right-border-coord 1.0d0
		 :top-border-line (constant-function 1.0d0)
		 :bottom-border-line (constant-function 0.0d0)
		 :thickening-coef-x 1
		 :thickening-coef-y 1)
      (gridbg "2 (init-grid)" grid)

      (let* ((left (make-instance 'primitive-variables
				  :phi 0.9
				  :rg 1.0
				  :ug 1000.0
				  :ul 1000.0))
	     (ug-right (ug left))
	     (ul-right (/ (+ (* (rg left) *Ro* *T*)
			     (* (- 1 (phi left)) *rl* (ul left) (ul left)))
			  (* *rl* (ul left))))
	     (phi-right (- 1
			   (/ (* (- 1 (phi left)) (ul left))
			      ul-right)))
	     (rg-right (/ (* (rg left) (phi left))
			  phi-right))
	     (right
	      (make-instance 'primitive-variables
			     :ug ug-right
			     :ul ul-right
			     :phi phi-right
			     :rg rg-right)))
	(set-splitted-field-2d-x grid
				 :left-vars left
				 :right-vars right))
      
      (gridbg "3 (set-field)" grid)
      (update-boundary-cells grid)
      (gridbg "4 (boundaries)" grid)
      (gridbg "start-grid" grid)
      (let ((newgrid (march grid
			    :finish-time 0.005
			    :finish-convergence 1.0d-6
			    :output-every-time 0.0001
			    :output-every-step 100
			    :cu cu
			    )))
	(gridbg "final-grid" newgrid)
	newgrid
	)
      )))



(defun test-kt-frolov-b (&key (cells-nx 100) (cells-ny 1) (cu 0.001) (output-dir #P"~/prog/clfpv/test-kt-frolov-b/"))
  "Тест из статьи Фролова с источниковыми членами. В статье обозначен как Б."
  (ensure-directories-exist output-dir)
  (let ((*DEFAULT-PATHNAME-DEFAULTS* output-dir))
    (let ((grid (make-instance 'grid2d-cv
			       :cells-amount-x cells-nx
			       :cells-amount-y cells-ny
			       :left-boundary-condition 'fixed
			       :right-boundary-condition 'fixed
			       :bottom-boundary-condition 'zeroe
			       :top-boundary-condition 'zeroe)))
      (gridbg "1 (instance)" grid)
      (init-grid grid
		 :left-border-coord 0.0d0
		 :right-border-coord 1.0d0
		 :top-border-line (constant-function 1.0d0)
		 :bottom-border-line (constant-function 0.0d0)
		 :thickening-coef-x 1
		 :thickening-coef-y 1)
      (gridbg "2 (init-grid)" grid)

      (let ((Pin (* 20 100000.0d0))
	    (Pout (* 10 100000.0d0))
	    (phi 0.01d0)
	    (ug 25.0d0)
	    (ul 30.0d0))
	(let ((left (make-instance 'primitive-variables
				   :phi phi
				   :P Pin
				   :ug ug
				   :ul ul))
	      (right (make-instance 'primitive-variables
				    :phi phi
				    :P Pout
				    :ug ug
				    :ul ul)))
	  (set-monotonous-field-2d-x grid
				     :left-vars left
				     :right-vars right)))
      
      (gridbg "3 (set-field)" grid)
      (update-boundary-cells grid)
      (gridbg "4 (boundaries)" grid)
      (gridbg "start-grid" grid)
      (let ((newgrid (march grid
			    :finish-convergence 1.0d-6
			    :output-every-time 0.0001
			    :output-every-step 10
			    :cu cu
			    )))
	(gridbg "final-grid" newgrid)
	newgrid
	)
      )))



(defun test-kt-frolov-d (&key (cells-nx 100) (cells-ny 1) (cu 0.001)
			   (perturbation-coef 0.01)
			   (output-dir #P"~/prog/clfpv/test-kt-frolov-d/"))
  "Тест из статьи Фролова с источниковыми членами. В статье обозначен как Г."
  (ensure-directories-exist output-dir)
  (let ((*DEFAULT-PATHNAME-DEFAULTS* output-dir))
    (let ((grid (make-instance 'grid2d-cv
			       :cells-amount-x cells-nx
			       :cells-amount-y cells-ny
			       :left-boundary-condition 'fixed
			       :right-boundary-condition 'fixed
			       :bottom-boundary-condition 'zeroe
			       :top-boundary-condition 'zeroe)))
      (gridbg "1 (instance)" grid)
      (init-grid grid
		 :left-border-coord 0.0d0
		 :right-border-coord 1.0d0
		 :top-border-line (constant-function 1.0d0)
		 :bottom-border-line (constant-function 0.0d0)
		 :thickening-coef-x 1
		 :thickening-coef-y 1)
      (gridbg "2 (init-grid)" grid)

      (let ((Pin (* 20 100000.0d0))
	    (Pout (* 10 100000.0d0))
	    (phi 0.01d0)
	    (ug 25.0d0)
	    (ul 30.0d0))
	(let ((left (make-instance 'primitive-variables
				   :phi phi
				   :P Pin
				   :ug ug
				   :ul ul))
	      (right (make-instance 'primitive-variables
				    :phi phi
				    :P Pout
				    :ug ug
				    :ul ul)))
	  (set-monotonous-field-2d-x grid
				     :left-vars left
				     :right-vars right)))

      ;; вносим возмущение поля
      (flet ((perturbate (i)
	       (1+ (* perturbation-coef
		      (sin (* (+ (* 2 i) 1) 0.5d0 pi))))))
	(let* ((left-index (index (min-x-index grid) 0))
	       (left-cell (cell grid left-index))
	       (right-index (index (max-x-index grid) 0))
	       (right-cell (cell grid right-index)))
	  (perturbate-field-x grid #'perturbate)
	  (setf (cell grid left-index) left-cell)
	  (setf (cell grid right-index) right-cell)))

      (gridbg "3 (set-field)" grid)
      (update-boundary-cells grid)
      (gridbg "4 (boundaries)" grid)
      (gridbg "start-grid" grid)
      (let ((newgrid (march grid
			    :finish-convergence 1.0d-6
			    :output-every-time 0.0001
			    :output-every-step 10
			    :cu cu
			    )))
	(gridbg "final-grid" newgrid)
	newgrid
	)
      )))

(defun test-kt-frolov-c (&key (cells-nx 100) (cells-ny 1) (cu 0.001)
			   (perturbation-coef 0.1)
			   (output-dir #P"~/prog/clfpv/test-kt-frolov-c/"))
  "Тест из статьи Фролова с источниковыми членами. В статье обозначен как В."
  (test-kt-frolov-d :cells-nx cells-nx
		    :cells-ny cells-ny
		    :cu cu
		    :perturbation-coef perturbation-coef
		    :output-dir output-dir)
  )