!#########################################################################
!		
!    Copyright (C) 2003-2012 Department of Physics and Astronomy,
!                            University of Rochester,
!                            Rochester, NY
!
!    problem.f90 of module CurrentSheet is part of AstroBEAR.
!
!    AstroBEAR is free software: you can redistribute it and/or modify	  
!    it under the terms of the GNU General Public License as published by 
!    the Free Software Foundation, either version 3 of the License, or    
!    (at your option) any later version.
!
!    AstroBEAR is distributed in the hope that it will be useful, 
!    but WITHOUT ANY WARRANTY; without even the implied warranty of
!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!    GNU General Public License for more details.
!
!    You should have received a copy of the GNU General Public License
!    along with AstroBEAR.  If not, see <http://www.gnu.org/licenses/>.
!
!#########################################################################
MODULE Problem
  USE DataDeclarations
  USE GlobalDeclarations
  USE PhysicsDeclarations
  USE Refinements
  USE Shapes
  !! @brief Reads the problem data file and performs a quick sanity check on the parameters.

 ! USE IFPORT
  IMPLICIT NONE
  PRIVATE
  
  PUBLIC ProblemModuleInit, ProblemGridInit, &
       ProblemBeforeStep, ProblemAfterStep, ProblemSetErrFlag, ProblemBeforeGlobalStep

  LOGICAL :: Equi
  REAL(KIND=qPrec) :: rho0,rho1,t0,t1,B0,B1,crad
  INTEGER, PARAMETER :: ResTest_FILEHANDLE = 32
CONTAINS
  SUBROUTINE ProblemModuleInit
    INTEGER :: iErr
    TYPE(RefinementDef), POINTER :: Refinement
    REAL(KIND=qPREC) :: d(3) = (/0.8,3.2,0.4/)

    CALL CreateRefinement(Refinement)
    CALL CreateShape(Refinement%Shape)
    CALL SetShapeType(Refinement%Shape,5,d)
    Refinement%Shape%velocity=(/0d0,0d0,0d0/)
    CALL SetShapeBounds(Refinement%Shape)
    Refinement%BufferCells=10
    Refinement%type=DEREFINE_OUTSIDE
  END SUBROUTINE ProblemModuleInit

  SUBROUTINE ProblemGridInit(Info)
	!! @brief Initializes the grid data according to the requirements of the problem.
	!! @param Info A grid structure.	
    TYPE (InfoDef) :: Info
    INTEGER :: i,j,k,iErr
    INTEGER :: rmbc,zrmbc
    INTEGER :: mx, my, mz
    REAL(KIND=qPrec) :: dx,Bx,By,Bz,Bp,Bxp,Byp,rho,rho0,rhoc,l,kw,t,a,pos(3)

    rmbc = levels(Info%level)%gmbc(1)!CoarsenRatio(Info%level-1) * mbc

    IF(nDim==2)THEN
       zrmbc=0
    ELSE
       zrmbc=rmbc
    END IF

    Info%q=0d0;Info%aux=0d0
    mx=Info%mX(1); my=Info%mX(2); mz=Info%mX(3); dx=levels(Info%level)%dx

    DO k=1-zrmbc,mz+zrmbc; DO j=1-rmbc,my+rmbc; DO i=1-rmbc, mx+rmbc
       pos=Info%xBounds(1:3,1)+(/REAL(i)-half,REAL(j)-half,REAL(k)-half/)*levels(Info%level)%dx
  
       B0=1.0;a=0.5;rho0=1.0;rhoc=0.2
       Bx=0.0; By=B0*tanh(pos(1)/a)
       rho=rho0*(cosh(pos(1)/a))**(-2)+rhoc
       t=0.5; l=25.6; kw=2.0*pi/l; Bp=0.0!1.0*kw
       Bxp=Bp*sin(kw*pos(1))*cos(kw*pos(2)); Byp=-Bp*cos(kw*pos(1))*sin(kw*pos(2))
       Bx=Bx+Bxp; By=By+Byp
       Info%q(i,j,k,1)=rho
       Info%q(i,j,k,iBx)=Bx
       Info%q(i,j,k,iBy)=By
       Info%q(i,j,k,iE)=rho*t/(gamma-1.)+0.5*(Bx**2+By**2)


    END DO; END DO; END DO
    IF (MaintainAuxArrays) THEN
       DO i=1-rmbc+1,mx+rmbc; DO j=1-rmbc,my+rmbc; DO k=1-zrmbc,mz+zrmbc
         Info%aux(i,j,k,1)=.5*(Info%q(i-1,j,k,iBx)+Info%q(i,j,k,iBx))
       END DO; END DO; END DO
       DO i=1-rmbc,mx+rmbc; DO j=1-rmbc+1,my+rmbc; DO k=1-zrmbc,mz+zrmbc
         Info%aux(i,j,k,2)=.5*(Info%q(i,j-1,k,iBy)+Info%q(i,j,k,iBy))
       END DO; END DO; END DO
       DO i=1-rmbc,mx+rmbc; DO j=1-rmbc,my+rmbc; DO k=1-zrmbc+1,mz+zrmbc
         Info%aux(i,j,k,3)=.5*(Info%q(i,j,k-1,iBz)+Info%q(i,j,k,iBz))
       END DO; END DO; END DO
    END IF

  END SUBROUTINE ProblemGridInit

  SUBROUTINE ProblemBeforeStep(Info)
	!! @brief Performs any tasks required before the advance step.
	!! @param Info A grid structure.	
    TYPE (InfoDef) :: Info
    INTEGER :: i,j
    INTEGER :: rmbc
    INTEGER :: mx,my
    INTEGER :: iErr

  END SUBROUTINE ProblemBeforeStep

  SUBROUTINE ProblemAfterStep(Info)
  	!! @brief Performs any post-step corrections that are required.
	!! @param Info A grid structure.	
    TYPE (InfoDef) :: Info
  END SUBROUTINE ProblemAfterStep

  SUBROUTINE ProblemSetErrFlag(Info)
  	!! @brief Sets error flags according to problem-specific conditions..
	!! @param Info A grid structure.	
    TYPE (InfoDef) :: Info
  END SUBROUTINE ProblemSetErrFlag

  SUBROUTINE ProblemBeforeGlobalStep(n)
    INTEGER :: n
  END SUBROUTINE ProblemBeforeGlobalStep

END MODULE Problem
