summaryrefslogtreecommitdiff
path: root/Dragon/src/DOORS_MOD.f90
blob: 9538892cc7514bcbb9b7fb4931ce0c13331b6059 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
MODULE DOORS_MOD
  USE GANLIB
CONTAINS
  SUBROUTINE DOORS(CDOOR,IPTRK,NMAT,NANIS,NUN,SIGG,SUNKNO,FUNKNO)
    !
    !---------------------------------------------------------------------
    !
    !Purpose:
    ! compute the product of a cross section times a flux unknow vector.
    !
    !Copyright:
    ! Copyright (C) 2025 Ecole Polytechnique de Montreal
    ! This library is free software; you can redistribute it and/or
    ! modify it under the terms of the GNU Lesser General Public
    ! License as published by the Free Software Foundation; either
    ! version 2.1 of the License, or (at your option) any later version
    !
    !Author(s): A. Hebert
    !
    !Parameters: input
    ! CDOOR   name of the geometry/solution operator.
    ! IPTRK   pointer to the tracking (L_TRACK signature).
    ! NMAT    number of mixtures in the macrolib.
    ! NANIS   number of Legendre components in the macrolib (=0: isotropic).
    ! NUN     total number of unknowns in vectors SUNKNO and FUNKNO.
    ! SIGG    cross section.
    ! FUNKNO  optional unknown vector. If not present, a flat flux
    !         approximation is assumed.
    !
    !Parameters: output
    ! SUNKNO  source vector. Volumes are included with BIVAC and TRIVAC
    !         trackings.
    !
    !---------------------------------------------------------------------
    !
    !----
    !  SUBROUTINE ARGUMENTS
    !----
    CHARACTER(LEN=12), INTENT(IN) :: CDOOR
    TYPE(C_PTR), INTENT(IN) :: IPTRK
    INTEGER, INTENT(IN) :: NMAT,NANIS,NUN
    REAL, DIMENSION(0:NMAT,NANIS+1), INTENT(IN) :: SIGG
    REAL, DIMENSION(NUN), INTENT(IN), OPTIONAL :: FUNKNO
    REAL, DIMENSION(NUN), INTENT(INOUT) :: SUNKNO
    !----
    !  LOCAL VARIABLES
    !----
    INTEGER, PARAMETER :: NSTATE=40
    INTEGER, DIMENSION(NSTATE) :: ISTATE
    !----
    !  ALLOCATABLE ARRAYS
    !----
    INTEGER, ALLOCATABLE, DIMENSION(:) :: MATCOD
    INTEGER, ALLOCATABLE, DIMENSION(:,:,:) :: KEYFLX
    REAL, ALLOCATABLE, DIMENSION(:) :: VOL
    !----
    !  RECOVER TRACKING PARAMETERS
    !  NFUNL: number of spherical harmonics components used to expand the
    !         flux and the sources.
    !  NANIS_TRK: number of components in the angular expansion of the flux
    !----
    CALL LCMGET(IPTRK,'STATE-VECTOR',ISTATE)
    NREG=ISTATE(1)
    IF(ISTATE(2).GT.NUN) CALL XABORT('DOORS: WRONG NUN.')
    IF(ISTATE(4).GT.NMAT) CALL XABORT('DOORS: WRONG NMAT.')
    NDIM=0
    NLIN=1
    NFUNL=1
    NANIS_TRK=1
    IF(CDOOR.EQ.'MCCG') THEN
      NANIS_TRK=ISTATE(6)
      NDIM=ISTATE(16)
      CALL LCMGET(IPTRK,'MCCG-STATE',ISTATE)
      NFUNL=ISTATE(19)
      NLIN=ISTATE(20)
    ELSE IF(CDOOR.EQ.'SN') THEN
      NFUNL=ISTATE(7)
      NLIN=ISTATE(8)
      NDIM=ISTATE(9)
      NLIN=NLIN**NDIM
      NLIN=NLIN*ISTATE(35)
      NANIS_TRK=ISTATE(16)
    ELSE IF(CDOOR.EQ.'BIVAC') THEN
      NLIN=ABS(ISTATE(8)) ! order of finite elements
      NFUNL=MAX(1,ISTATE(14))
      NANIS_TRK=ABS(ISTATE(16))
    ELSE IF(CDOOR.EQ.'TRIVAC') THEN
      NLIN=ABS(ISTATE(9)) ! order of finite elements
      NLFUNL=MAX(1,ISTATE(30))
      NANIS_TRK=ABS(ISTATE(32))
    ENDIF
    ALLOCATE(MATCOD(NREG),VOL(NREG),KEYFLX(NREG,NLIN,NFUNL))
    KEYFLX(:NREG,:NLIN,:NFUNL)=0
    CALL LCMLEN(IPTRK,'MATCOD',ILNLCM,ITYLCM)
    IF(ILNLCM.NE.NREG) CALL XABORT('DOORS: INCOMPATIBLE NUMBER OF REGIONS.')
    CALL LCMGET(IPTRK,'MATCOD',MATCOD)
    CALL LCMGET(IPTRK,'VOLUME',VOL)
    IF((CDOOR.EQ.'MCCG').OR.(CDOOR.EQ.'SN')) THEN
      CALL LCMGET(IPTRK,'KEYFLX$ANIS',KEYFLX)
    ELSE
      CALL LCMGET(IPTRK,'KEYFLX',KEYFLX)
    ENDIF
    !----
    !  PERFORM SIGG*FUNKNO MULTIPLICATION
    !----
    IF(CDOOR.EQ.'SN') THEN
      CALL DOORS_SN(IPTRK,NANIS,NREG,NMAT,NUN,MATCOD,SIGG,SUNKNO,FUNKNO)
    ELSE IF(CDOOR.EQ.'BIVAC') THEN
      CALL DOORS_BIV(IPTRK,NANIS,NREG,NMAT,NUN,MATCOD,VOL,SIGG,SUNKNO,FUNKNO)
    ELSE IF(CDOOR.EQ.'TRIVAC') THEN
      CALL DOORS_TRI(IPTRK,NANIS,NREG,NMAT,NUN,MATCOD,VOL,SIGG,SUNKNO,FUNKNO)
    ELSE IF(PRESENT(FUNKNO)) THEN
      ! general case
      IF((NANIS.EQ.0).OR.(NFUNL.EQ.1).OR.(NANIS_TRK.EQ.1)) THEN
        ! LAB isotropy or transport correction
        DO IR=1,NREG
          IBM=MATCOD(IR)
          IF(IBM.LE.0) CYCLE
          DO IE=1,NLIN
            IND=KEYFLX(IR,IE,1)
            SUNKNO(IND)=SUNKNO(IND)+SIGG(IBM,1)*FUNKNO(IND)
          ENDDO
        ENDDO ! IR
      ELSE
        ! spherical harmonics expansion of the flux and source
        DO IR=1,NREG
          IBM=MATCOD(IR)
          IF(IBM.LE.0) CYCLE
          DO IAL=0,MIN(NFUNL-1,NANIS,NANIS_TRK-1)
            FACT=REAL(2*IAL+1)
            DO IAM=0,MIN(NFUNL-1,NANIS,NANIS_TRK-1)
              DO IE=1,NLIN
                IND=0
                IF(NDIM.EQ.3) THEN
                  IND=KEYFLX(IR,IE,1+IAL*NANIS_TRK+IAM)
                ELSE IF((NDIM.EQ.2).AND.(IAM.LE.IAL)) THEN
                  IND=KEYFLX(IR,IE,1+IAL*(IAL+1)/2+IAM)
                ELSE IF(IAM.EQ.IAL) THEN
                  IND=KEYFLX(IR,IE,1+IAL)
                ENDIF
                IF(IND.EQ.0) THEN
                  CYCLE
                ELSE IF(IND.GT.NUN) THEN
                  CALL XABORT('DOORS: NUN OVERFLOW.')
                ENDIF
                SUNKNO(IND)=SUNKNO(IND)+FACT*SIGG(IBM,IAL+1)*FUNKNO(IND)
              ENDDO ! IE
            ENDDO ! IAM
          ENDDO ! IAL
        ENDDO ! IR
      ENDIF
    ELSE
      ! general case (flat flux)
      DO IR=1,NREG
        IND=KEYFLX(IR,1,1)
        SUNKNO(IND)=SUNKNO(IND)+SIGG(MATCOD(IR),1)
      ENDDO
    ENDIF
    DEALLOCATE(KEYFLX,VOL,MATCOD)
  END SUBROUTINE DOORS
END MODULE DOORS_MOD