MODULE test
TYPE YlmEvaluate_Type
  LOGICAL :: Defined         = .FALSE.
  ! Control variables
  INTEGER      :: NumDimensions     = 0                        ! Number of spatial dimensions in problem (1,2,3)
  INTEGER      :: AngularOrder      = 0                        ! Expansion Order of the Y[L,M] functions (1,2,3,4,5,...)
  INTEGER      :: EvenTerms         = 0                        ! Number of even parity Y[L,M] functions
  INTEGER      :: OddTerms          = 0                        ! Number of odd parity Y[L,M] functions
  CHARACTER*16 :: QuadType          = 'UNDEFINED'              ! The Quadrature type used to evaluate the Y[L,M] functions
  CHARACTER*16 :: SphericalCoverage = 'UNDEFINED'              ! The Quadrature coverage over the spherical surface
  INTEGER      :: QuadOrder         = 0                        ! The Quadrature Order used to evaluate the Y[L,M] functions
   ! Angular Quadrature set that the functions are evaluated at
!MTN   TYPE (GaussInt) Quadrature
   ! The evaluated YLM terms and indexing information
!MTN   REAL    (KIND=K_YLM_COEF), DIMENSION(:,:), POINTER     :: EvenYLM    ! Evaluated spherical harmonics (EvenTerms,Quadrature%NumPoints)
  INTEGER,                   DIMENSION(:,:), POINTER     :: EvenIndex  ! L,M index of all the even parity terms (EvenTerms,2)
!MTN   REAL    (KIND=K_YLM_COEF), DIMENSION(:,:), POINTER     :: OddYLM     ! Evaluated spherical harmonics (OddTerms,Quadrature%NumPoints)
!  INTEGER,                   DIMENSION(:,:), POINTER     :: OddIndex   ! L,M index of all the odd parity terms  (OddTerms,2)
END TYPE YlmEvaluate_Type
TYPE MatrixMethods_Data_Type
   ! Global communicator info
   INTEGER                          :: Parallel_Comm    = 0          ! The UNIC communicator id
   INTEGER                          :: Parallel_Group   = 0          ! The group id for the UNIC communicator
   INTEGER                          :: Parallel_Rank    = 0          ! The rank of this processor in the UNIC communicator
   INTEGER                          :: Parallel_Size    = 0          ! The size of the UNIC communicator
   ! Overriding solution parameters
   LOGICAL                          :: SyntheticPresent = .FALSE.    ! Logical flag indicating that the synthetic diffusion equation is necessary
   INTEGER                          :: NumDimensions    = 0          ! The number of spatial dimensions in the problem
   INTEGER                          :: AngularOrder     = 0          ! The angular order of the flux expansion
   ! Characteristics of the multigroup solution
   INTEGER                          :: Preconditioner   = 0          ! Indicates which preconditioner to use
   LOGICAL                          :: TchebychevAccel  = .TRUE.     ! Indicates that Tchebychev acceleration is implemented
   LOGICAL                          :: UpDownScattering = .FALSE.    ! Indicates that up and down scattering are present
   INTEGER                          :: Last_DownScatterGroup = 0     ! The last group above which (1-LDSG) there is only downscattering
   LOGICAL                          :: FissionIsPresent = .FALSE.    ! Indicates that fission is present in the system
   DOUBLE PRECISION                 :: Iterative_Improvement = 0.15d0! The iterative improvement to enforce on each consecutive level of the flux solve tree
   ! Fixed source information
   LOGICAL                          :: FixedSourceIsPresent = .FALSE.! Indicates that a fixed source is present
   INTEGER                          :: FixedSource_MaxEven = 0       ! Indicates the maximum number of even-parity fixed source terms present
   INTEGER                          :: FixedSource_MaxOdd  = 0       ! Indicates the maximum number of odd parity fixed source terms present
   ! Discrete ordinates based info
   CHARACTER*16                     :: CubatureType     = 'arggh'    ! The angular cubature type
   CHARACTER*16                     :: CoverageType     = 'arghh'    ! The angular cubature coverage type
   INTEGER                          :: Angles           = 0          ! The number of directions in the angular cubature (first-order)
   INTEGER                          :: Angles_Even      = 0          ! The number of even-parity directions in the angular cubature (second-order)
   INTEGER                          :: Angles_Odd       = 0          ! The number of odd-parity directions in the angular cubature (odd-order)
   ! Spherical harmonics based info
   INTEGER                          :: Ylm_Even         = 0          ! The number of even-parity spherical harmonics
   INTEGER                          :: Ylm_Odd          = 0          ! The number of odd-parity spherical harmonics
   ! Scattering Angular Order
   INTEGER                          :: ScatteringOrder  = 0          ! The angular order of the scattering expansion
   INTEGER                          :: Scattering_Even  = 0          ! The number of even-parity spherical harmonics associated with ScatteringOrder
   ! Angular cubature and matrices
   TYPE (YlmEvaluate_Type)          :: EvaluatedYlm                  ! The discrete ordinates quadrature and evaluated spherical harmonics
!   TYPE (YLM_Matrices_Type)         :: AngularMatrices               ! The angular matrices needed in the matrix methods
!   TYPE (FE_Matrices_Type)          :: SpatialMatrices               ! The spatial matrices needed in the matrix methods
!   TYPE (BC_Assignment_Type)        :: ReflectedBC                   ! The outward normal assignment by vertex of reflected boundary conditions
!   TYPE (BC_Reflected_Flags_Type)   :: ReflectedFlags                ! The flag for every local element indicating whether reflected boundary conditions apply
!   TYPE (BC_Assignment_Type)        :: VacuumBC                      ! The outward normal assignment by "global" boundary surface of vacuum boundary conditions

!   TYPE (MatrixMethods_MatVec_Type) :: MatVec                        ! The PETSc matrices and vectors used in the matrix based solver
END TYPE MatrixMethods_Data_Type
!TYPE NE_NT_ParallelFlux
!   INTEGER                        :: Parallel_comm           = 0  !      Specifies the communication process id of this task
!   INTEGER                        :: Parallel_Rank           = 0  ! (R)  Specifies the rank of the process in the parallel environment
!   INTEGER                        :: Parallel_Size           = 0  ! (NP) Specifies the number of processors in the parallel environment task
   ! Control process for storing the global flux solution to disk for restart capabilities
!   INTEGER                        :: IterationsPerDump       = 0  ! The number of iterations to skip between each flux dump
!   INTEGER                        :: DumpOption              = 1  ! The flag indicating which backup file is to be written next
                                                                  ! Two files are used to prevent overwrite failure due to disk filling
!   CHARACTER*80                   :: BackupFile1             = 'restart01.neflux'
!   CHARACTER*80                   :: BackupFile2             = 'restart02.neflux'
   ! Global level variables which should span all locally defined ones
!   DOUBLE PRECISION               :: FundamentalModeEigenvalue = 0.0
!   LOGICAL                        :: Global_Defined          = .FALSE.
!   INTEGER                        :: Global_NumGroups        = 0  ! The number of groups in the flux solution
!   INTEGER                        :: Global_AngularDOF       = 0  ! The number of angular degrees of freedom
!   INTEGER                        :: Global_SpatialDOF       = 0  ! The number of spatial degrees of freedom
!   INTEGER                        :: Global_Surf_Spatial     = 0  ! The total number of spatial degrees of freedom used for the boundary flux
!   INTEGER                        :: Global_Surf_Angular     = 0  ! The number of angular degrees of freedom used for the boundary flux
!   INTEGER                        :: Global_MaxSpace         = 0  ! The maximum of Global_SpatialDOF and Global_Surf_Spatial
   ! A MPI_ALLREDUCE is used to merge the angular flux from all processors
   ! To collect the global flux vectors on a single processor, the local flux solution should be copied into this vector by angle by group (i.e. as desired)
   ! The flux reduction vector is defined (0:X) to avoid if statements in the element assigned flux solution approach
!MTN   REAL (KIND=NE_NT_Flux_Real),DIMENSION(:),    POINTER :: Global_FluxReduction1 ! (0:larger of Global_SpatialDOF or Global_Surf_Spatial)
!MTN   REAL (KIND=NE_NT_Flux_Real),DIMENSION(:),    POINTER :: Global_FluxReduction2 ! (0:larger of Global_SpatialDOF or Global_Surf_Spatial)
   ! The following should will only exist on rank zero processors where the group flux is collected and distributed
!MTN   REAL (KIND=NE_NT_Flux_Real),DIMENSION(:,:,:),POINTER :: Global_FluxSolution  ! (Global_SpatialDOF,Global_AngularDOF,Global_NumGroups)
!MTN   REAL (KIND=NE_NT_Flux_Real),DIMENSION(:,:,:),POINTER :: Global_BoundaryFlux  ! (Global_Surf_Spatial,Global_Surf_Angular,Global_NumGroups)
   ! Local flux solution implementation
!   LOGICAL                        :: Local_Defined           = .FALSE.
!   INTEGER                        :: Local_NumGroups         = 0  ! The number of energy groups assigned to this processor
!   INTEGER                        :: Local_FluxPieces        = 0  ! The number of iterative (new/old/really old,...) pieces used on this processor
!   INTEGER                        :: Local_AngularDOF        = 0  ! The number of angular degrees of freedom assigned to this processor
!   INTEGER                        :: Local_SpatialDOF        = 0  ! The number of spatial degrees of freedom assigned to this processor
!   INTEGER                        :: Local_Surf_Spatial      = 0  ! The total number of spatial degrees of freedom used for the boundary flux
!   INTEGER                        :: Local_Surf_Angular      = 0  ! The number of angular degrees of freedom used for the boundary flux
!mtn   REAL (KIND=NE_NT_Flux_Real),DIMENSION(:,:,:,:),POINTER :: Local_FluxSolution ! (Local_SpatialDOF,Local_AngularDOF,Local_FluxPieces,Local_NumGroups)
!mtn   REAL (KIND=NE_NT_Flux_Real),DIMENSION(:,:,:),  POINTER :: Local_BoundaryFlux ! (Local_Surf_Spatial,Local_Surf_Angular,Local_NumGroups)
!END TYPE
TYPE HomogenizedXS_Composition
!   LOGICAL (KIND=K_L)       :: Defined        = .FALSE.           ! Indicates structure is defined
!   CHARACTER(K_HXS_Char)    :: Name           = 'Undefined' ! Name of the composition
   !NTEGER (KIND=K_HXS_Igroups) :: NumGroups      = 0 ! G       ! Number of energy groups
!   LOGICAL (KIND=K_L)       :: VoidMaterial   = .FALSE.     ! Void composition
!   LOGICAL (KIND=K_L)       :: Fissionable    = .FALSE.     ! Fissionable composition
!   LOGICAL (KIND=K_L)       :: File_Chi       = .FALSE.     ! Indicates whether file wide chi is used (true) or not (false)
!   LOGICAL (KIND=K_L)       :: FixedSource    = .FALSE.     ! Indicates whether a fixed source is present
!   INTEGER (KIND=K_HXS_Iparity) :: EvenFixedTerms = 0 ! EF      ! Number of even-parity fixed source moments (see ordering description)
!   INTEGER (KIND=K_HXS_Iparity) :: OddFixedTerms  = 0 ! OF      ! Number of odd-parity  fixed source moments (see ordering description)
!   INTEGER (KIND=K_HXS_Iparity) :: ScatLegendre   = 0 ! L       ! Number of Legendre expansion moments of the scattering
!   REAL (KIND=K_HXS_data), DIMENSION(:),    POINTER :: Total             ! (G)    Total cross section
!   REAL (KIND=K_HXS_data), DIMENSION(:),    POINTER :: PowerConversion   ! (G)    Power Conversion Factor   [ Watts / (n-cm/sec) ]
!   REAL (KIND=K_HXS_data), DIMENSION(:),    POINTER :: Absorption        ! (G)    Absorption
!   REAL (KIND=K_HXS_data), DIMENSION(:,:),  POINTER :: WithinGroup       ! (L,G)  Within group scattering moments
!   REAL (KIND=K_HXS_data), DIMENSION(:),    POINTER :: Fission           ! (G)    Fission cross section
!   REAL (KIND=K_HXS_data), DIMENSION(:),    POINTER :: NuFission         ! (G)    Nu*Fission cross section
!   REAL (KIND=K_HXS_data), DIMENSION(:),    POINTER :: Chi               ! (G)    The fission emission spectrum
!   REAL (KIND=K_HXS_data), DIMENSION(:,:),  POINTER :: EvenFixedSource   ! (EF,G) Magnitude of the fixed source for each composition
!   REAL (KIND=K_HXS_data), DIMENSION(:,:),  POINTER :: OddFixedSource    ! (OF,G) Magnitude of the fixed source for each composition
   ! The following is only defined if the number of groups is > 1
   INTEGER,               DIMENSION(:),    POINTER :: StartUpScatter    ! (G)    Start of the upscattering = US ... 1 <= US < g
   INTEGER,               DIMENSION(:),    POINTER :: EndDownScatter    ! (G)    End of the downscattering = DS ... g <  DS <= G
!   TYPE (HomogenizedXS_Scattering), DIMENSION(:), POINTER :: Scattering ! (G)    Scattering into -> g' from g.
END TYPE HomogenizedXS_Composition
TYPE HomogenizedXS_Library
   LOGICAL :: Defined = .FALSE.                       ! Indicates whether structure is defined or not
   LOGICAL :: CrossSectionsWereUpdated = .FALSE.      ! Indicates that these cross sections were altered
!   INTEGER (KIND=K_HXS_Igroups) :: NumGroups          ! G         ! The number of energy groups in the data set
!   INTEGER (KIND=K_HXS_IComps)  :: NumCompositions    ! C         ! The number of compositions in the data set
!   LOGICAL (KIND=K_L) :: ThereIsAFileChi              ! Indicates that there is a file chi vector present
   ! The actual cross section data
!   REAL (KIND=K_HXS_data),          DIMENSION(:), POINTER :: FileChi           ! (G)   The fission emission spectrum
   TYPE (HomogenizedXS_Composition),DIMENSION(:), POINTER :: Composition       ! (C) ! The cross section for all compositions
END TYPE HomogenizedXS_Library
INTEGER, PARAMETER :: KIND_L8  = 1     ! KIND NUMBERS FOR  8 bit LOGICAL (01 to 00)

TYPE HomogenizedXS_InnerIteration
   LOGICAL (KIND=KIND_L8)                            :: Defined = .FALSE.  ! Indicates that this structure is defined
!   REAL (KIND=K_HXS_data),DIMENSION(:),  POINTER :: Total              ! (B) The total cross section assigned by Block
!   REAL (KIND=K_HXS_data),DIMENSION(:,:),POINTER :: WithinGroup        ! (L,B) The within group scattering moments by Block
END TYPE HomogenizedXS_InnerIteration  
TYPE HomogenizedXS_BlockAssigned
   LOGICAL     :: Defined     = .FALSE.   ! Indicates that the Block information is defined
   INTEGER     :: NumBlocks   = 0         ! B ! The number of Blocks present in the mesh file
   INTEGER     :: MaxLegendre = 0         ! L ! The maximum number of Legendre terms in the mesh file
   INTEGER     :: NumGroups   = 0
   INTEGER, DIMENSION(:),   POINTER    :: BlockComposition  ! (B) The composition number that each Block is assigned to
   ! An optional data structure for quick access to
   TYPE (HomogenizedXS_InnerIteration) :: ForInnerIteration
END TYPE HomogenizedXS_BlockAssigned
TYPE EvenParitySource_Block
   LOGICAL (KIND=KIND_L8) :: Defined = .FALSE.
   INTEGER :: Points_Space    = 0 ! The number of spatial terms per element in the current block
   INTEGER :: NumEvenParity   = 0 ! The number of even-parity moments in the scattering kernel
   INTEGER :: NumOddParity    = 0 ! The number of odd-parity moments in the scattering kernel
   INTEGER :: NumElements     = 0 ! The number of elements in this block
   LOGICAL :: Fissionable     = .FALSE.
   DOUBLE PRECISION, DIMENSION(:,:,:,:),   POINTER :: Even_Source ! (Points_Space,NumEvenParity,NumElements,NumGroups)  even- and odd-parity fixed and scattering source
   DOUBLE PRECISION, DIMENSION(:,:,:,:,:), POINTER :: Odd_Source  ! (Points_Space,NumOddParity,NumElements,NumGroups,2) odd-parity flux (1) and odd-parity source (2)
   DOUBLE PRECISION, DIMENSION(:,:,:),     POINTER :: Fission     ! (Points_Space,NumElements,FissionMoments)           Fission source
END TYPE EvenParitySource_Block
TYPE EvenParitySource_Type
   LOGICAL  (KIND=KIND_L8)        :: Defined    = .FALSE.            ! Indicates whether structure is defined
   INTEGER                        :: NumGroups  = 0                  ! The number of groups in the problem
   INTEGER                        :: NumBlocks  = 0                  ! The number of blocks in the mesh data
   INTEGER                        :: FissionMoments = 0              ! The number of fission source moments that are stored (2 is the minimum needed for eigenvalue)
   INTEGER, DIMENSION(:), POINTER :: Index_Fission                   ! These indicate which terms are new(1), old(2), older(3), ... oldest(FissionMoments)
   DOUBLE PRECISION               :: ScatteringStorage = 0.0d0       ! The total storage for the scattering source
   DOUBLE PRECISION               :: FissionStorage = 0.0d0          ! The total storage for the fission source
   TYPE (EvenParitySource_Block), DIMENSION(:), POINTER :: BlockData ! (NumBlocks) Each blocks scattering source contribution
END TYPE EvenParitySource_Type
TYPE NE_NT_ParallelMesh
   LOGICAL                        :: Defined                 = .false.
!   TYPE (ANLNEFE_FEMMESH)         :: Global_Mesh                  ! The finite element mesh data structure assigned to rank 0
!   TYPE (ANLNEFE_FEMMESH)         :: Local_Mesh                   ! The finite element mesh data structure assigned to this processor
   INTEGER                        :: Parallel_comm           = 0  !      Specifies the communication process id of this task
   INTEGER                        :: Parallel_Rank           = 0  ! (R)  Specifies the rank of the process in the parallel environment
   INTEGER                        :: Parallel_Size           = 0  ! (NP) Specifies the number of processors in the parallel environment task
   INTEGER                        :: Global_NumMeshPoints    = 0  ! The global number of vertices in the mesh
   INTEGER                        :: Global_NumElements      = 0  ! The global number of elements in the mesh
   INTEGER                        :: Processor_NumMeshPoints = 0  ! = Local_NumMeshPoints + Local_GhostMeshPoints
   INTEGER                        :: Processor_NumElements   = 0  ! The number of elements visable to this processor
   INTEGER                        :: Local_NumMeshPoints     = 0  ! The number of local mesh points assigned to this processor
   INTEGER                        :: Local_GhostMeshPoints   = 0  ! The number of ghost mesh points not assigned to this processor
   INTEGER, DIMENSION(:), POINTER :: Parallel_Vertex_Rank         ! (Global_NumMeshPoints) The rank assignment (0:NP-1) for all vertices in the mesh
   INTEGER, DIMENSION(:), POINTER :: Parallel_Element_Rank        ! (Global_NumElements)   The rank assignment (0:NP-1) for all elements in the mesh
   INTEGER, DIMENSION(:), POINTER :: Vertex_Local_To_Global       ! (Processor_NumMeshPoints) The mapping from the local vertices to the global list
   INTEGER, DIMENSION(:), POINTER :: Element_Local_To_Global      ! (Processor_NumElements)   The mapping from the local elements to the global list
END TYPE
CONTAINS
SUBROUTINE SN2ND_Update_Scattering(Output_Unit,DebugSetup,DebugFormation,DebugOuter,                     &
                                   Group,Space_Visable,Scattering_Even,PNWithinGroupNew,PNWithinGroupOld)
!                                   SN2ND_Data,NE_NT_MeshData,NE_NT_HXS_Library,NE_NT_BlockAssigned,Storage_Source)
!USE MatrixMethods          ! Give access to the primary storage repository for the SN2ND solver
!USE NE_NT_Mesh             ! Give access to the parallel mesh data structure
!USE HomogenizedXS          ! Give access to the homogenized cross section data structure
!USE EvenParitySource       ! Give access to the Even-parity scattering and fission source data storage structure
IMPLICIT NONE
! Passed in
INTEGER           Output_Unit,DebugSetup,DebugFormation,DebugOuter
INTEGER           Group
INTEGER           Space_Visable     ! The number of visable spatial vertices
INTEGER           Scattering_Even   ! The number of even-parity angular moments we are projecting to
DOUBLE PRECISION  PNWithinGroupNew(Space_Visable,Scattering_Even)
DOUBLE PRECISION  PNWithinGroupOld(Space_Visable,Scattering_Even)
TYPE (MatrixMethods_Data_Type)     :: SN2ND_Data
!TYPE (NE_NT_ParallelMesh)          :: NE_NT_MeshData
!TYPE (HomogenizedXS_Library)       :: NE_NT_HXS_Library
!TYPE (HomogenizedXS_BlockAssigned) :: NE_NT_BlockAssigned
!TYPE (EvenParitySource_Type)       :: Storage_Source
! Local
INTEGER NumGroups,NumLegendre,ScatteringOrder,Isym
INTEGER Block,Comp
INTEGER NumElements,Element
INTEGER Points_Space,Space
INTEGER EvenMoment
INTEGER Scattering_Odd
INTEGER Storage_Scattering_Even,Storage_Scattering_Odd
INTEGER IOS
       NumElements     =  SN2ND_Data%EvaluatedYlm%NumDimensions
       NumElements     = Scattering_Odd
END SUBROUTINE SN2ND_Update_Scattering
END MODULE test
