summaryrefslogtreecommitdiff
path: root/Dragon/src/BRERTD.f90
blob: 9a62fcaa52f79744e554c6ab99c76b5dc3950e08 (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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
SUBROUTINE BRERTD(IELEM,ICOL,NGRP,DELX,DIFF,SIGT,SUNXS,JXM,JXP,IMPX, &
& FHOMM,FHOMP)
!
!-----------------------------------------------------------------------
!
!Purpose:
! Compute the Raviart-Thomas boundary fluxes for a single node.
!
!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
! IELEM   Raviart-Thomas polynomial order.
! ICOL    Raviart-Thomas polynomial integration type.
! NGRP    number of energy groups.
! DELX    node width along X-axis.
! DIFF    diffusion coefficient array (cm).
! SIGT    total XS (cm^-1).
! SUNXS   production (fission + scattering) cross sections. The second
!         dimension is for primary neutrons.
! JXM     left boundary currents.
! JXP     right boundary currents.
! IMPX    print flag.
!
!Parameters: output
! FHOMM   left boundary fluxes.
! FHOMP   right boundary fluxes.
!
!-----------------------------------------------------------------------
  USE GANLIB
  !
  !----
  !  subroutine arguments
  !----
  INTEGER, INTENT(IN) :: IELEM,ICOL,NGRP,IMPX
  REAL, INTENT(IN) :: DELX
  REAL, DIMENSION(NGRP), INTENT(IN) :: DIFF,JXM,JXP
  REAL, DIMENSION(NGRP), INTENT(IN) :: SIGT
  REAL, DIMENSION(NGRP,NGRP), INTENT(IN) :: SUNXS
  REAL, DIMENSION(NGRP), INTENT(OUT) :: FHOMM,FHOMP
  !----
  !  LOCAL VARIABLES
  !----
  TYPE(C_PTR) IPTRK
  REAL QQ(5,5)
  !----
  !  ALLOCATABLE ARRAYS
  !----
  REAL, DIMENSION(:,:), ALLOCATABLE :: R,V,SYS,FUNKNO
  !----
  !  RECOVER FINITE ELEMENT UNIT MATRICES.
  !----
  CALL LCMOP(IPTRK,'***DUMMY***',0,1,0)
  CALL BIVCOL(IPTRK,IMPX,IELEM,ICOL)
  ALLOCATE(V(IELEM+1,IELEM),R(IELEM+1,IELEM+1))
  CALL LCMSIX(IPTRK,'BIVCOL',1)
  CALL LCMGET(IPTRK,'V',V)
  CALL LCMGET(IPTRK,'R',R)
  CALL LCMSIX(IPTRK,' ',2)
  CALL LCMCL(IPTRK,2)
  !----
  !  LEAKAGE-REMOVAL SYSTEM MATRIX ASSEMBLY.
  !----
  ALLOCATE(SYS(IELEM*NGRP,IELEM*NGRP+1))
  SYS(:IELEM*NGRP,:IELEM*NGRP+1)=0.0
  DO I0=1,IELEM
    DO J0=1,IELEM
      QQ(I0,J0)=0.0
      DO K0=2,IELEM
        QQ(I0,J0)=QQ(I0,J0)+V(K0,I0)*V(K0,J0)/R(K0,K0)
      ENDDO
    ENDDO
  ENDDO
  INX=IELEM*NGRP+1
  DO IG=1,NGRP
    DO J0=1,IELEM
      JND1=(IG-1)*IELEM+J0
      SYS(JND1,JND1)=SYS(JND1,JND1)+DELX*SIGT(IG)
      DO K0=1,IELEM
        IF(QQ(J0,K0).EQ.0.0) CYCLE
        KND1=(IG-1)*IELEM+K0
        SYS(JND1,KND1)=SYS(JND1,KND1)+QQ(J0,K0)*DIFF(IG)/DELX
      ENDDO
      SYS(JND1,INX)=SYS(JND1,INX)-V(1,J0)*JXM(IG)-V(IELEM+1,J0)*JXP(IG)
    ENDDO
  ENDDO
  !----
  !  SOURCE SYSTEM MATRIX ASSEMBLY.
  !----
  DO IG=1,NGRP
    DO JG=1,NGRP
      DO J0=1,IELEM
        JND1=(IG-1)*IELEM+J0
        JND2=(JG-1)*IELEM+J0
        SYS(JND1,JND2)=SYS(JND1,JND2)-DELX*SUNXS(IG,JG) ! IG <-- JG
      ENDDO
    ENDDO
  ENDDO
  !----
  !  SOLVE A ONE-NODE PROBLEM.
  !----
  CALL ALSB(IELEM*NGRP,1,SYS,IER,IELEM*NGRP)
  IF(IER.NE.0) CALL XABORT('BRERTD: SINGULAR MATRIX.')
  ALLOCATE(FUNKNO(IELEM,NGRP))
  DO IG=1,NGRP
    DO J0=1,IELEM
      FUNKNO(J0,IG)=SYS((IG-1)*IELEM+J0,IELEM*NGRP+1)
    ENDDO
  ENDDO
  DEALLOCATE(SYS,R,V)
  !----
  !  COMPUTE NODAL SURFACE FLUXES
  !----
  DENOM=REAL(IELEM*(IELEM+1))
  FHOMM(:NGRP)=0.0
  FHOMP(:NGRP)=0.0
  DO IG=1,NGRP
    IF(ICOL.EQ.1) THEN
      ! NEM relations
      IF(IELEM.EQ.1) THEN
        FHOMM(IG)=FUNKNO(1,IG)+((1./3.)*JXM(IG)+(1./6.)*JXP(IG))*DELX/DIFF(IG)
        FHOMP(IG)=FUNKNO(1,IG)-((1./6.)*JXM(IG)+(1./3.)*JXP(IG))*DELX/DIFF(IG)
      ELSE IF(IELEM.EQ.2) THEN
        FHOMM(IG)=FUNKNO(1,IG)-(5.0*SQRT(3.0)/6.0)*FUNKNO(2,IG)+((1./8.)*JXM(IG)- &
        & (1./24.)*JXP(IG))*DELX/DIFF(IG)
        FHOMP(IG)=FUNKNO(1,IG)+(5.0*SQRT(3.0)/6.0)*FUNKNO(2,IG)-(-(1./24.)*JXM(IG)+ &
        & (1./8.)*JXP(IG))*DELX/DIFF(IG)
      ELSE IF(IELEM.EQ.3) THEN
        FHOMM(IG)=FUNKNO(1,IG)-(5.0*SQRT(3.0)/6.0)*FUNKNO(2,IG)+(7.0*SQRT(5.0)/10.0)*FUNKNO(3,IG)+ &
        & ((1./15.)*JXM(IG)+(1./60.)*JXP(IG))*DELX/DIFF(IG)
        FHOMP(IG)=FUNKNO(1,IG)+(5.0*SQRT(3.0)/6.0)*FUNKNO(2,IG)+(7.0*SQRT(5.0)/10.0)*FUNKNO(3,IG)- &
        & ((1./60.)*JXM(IG)+(1./15.)*JXP(IG))*DELX/DIFF(IG)
      ELSE
        CALL XABORT('BRERTD: IELEM OVERFLOW.')
      ENDIF
    ELSE IF(ICOL.EQ.2) THEN
      ! MCFD relations
      FHOMM(IG)=JXM(IG)*DELX/(DIFF(IG)*DENOM)
      FHOMP(IG)=-JXP(IG)*DELX/(DIFF(IG)*DENOM)
      DO J0=1,IELEM
        FP=SQRT(REAL(2*J0-1))*(1.0-REAL(J0*(J0-1))/DENOM)
        FM=FP*(-1.0)**(J0-1)
        FHOMM(IG)=FHOMM(IG)+FP*(-1.0)**(J0-1)*FUNKNO(J0,IG)
        FHOMP(IG)=FHOMP(IG)+FP*FUNKNO(J0,IG)
      ENDDO
    ELSE IF(ICOL.EQ.3) THEN
      IF(IELEM.EQ.1) THEN
        FHOMM(IG)=FUNKNO(1,IG)+((1./4.)*JXM(IG)+(1./4.)*JXP(IG))*DELX/DIFF(IG)
        FHOMP(IG)=FUNKNO(1,IG)-((1./4.)*JXM(IG)+(1./4.)*JXP(IG))*DELX/DIFF(IG)
      ELSE IF(IELEM.EQ.2) THEN
        FHOMM(IG)=FUNKNO(1,IG)-SQRT(3.0)*FUNKNO(2,IG)+((1./12.)*JXM(IG)- &
        & (1./12.)*JXP(IG))*DELX/DIFF(IG)
        FHOMP(IG)=FUNKNO(1,IG)+SQRT(3.0)*FUNKNO(2,IG)-(-(1./12.)*JXM(IG)+ &
        & (1./12.)*JXP(IG))*DELX/DIFF(IG)
      ELSE IF(IELEM.EQ.3) THEN
        FHOMM(IG)=FUNKNO(1,IG)-(5.0*SQRT(3.0)/6.0)*FUNKNO(2,IG)+SQRT(5.0)*FUNKNO(3,IG)+ &
        & ((1./24.)*JXM(IG)+(1./24.)*JXP(IG))*DELX/DIFF(IG)
        FHOMP(IG)=FUNKNO(1,IG)+(5.0*SQRT(3.0)/6.0)*FUNKNO(2,IG)+SQRT(5.0)*FUNKNO(3,IG)- &
        & ((1./24.)*JXM(IG)+(1./24.)*JXP(IG))*DELX/DIFF(IG)
      ELSE
        CALL XABORT('BRERTD: IELEM OVERFLOW.')
      ENDIF
    ELSE
      CALL XABORT('BRERTD: ICOL OVERFLOW.')
    ENDIF
    IF(IMPX.GT.0) THEN
      WRITE(6,'(46H BRERTD: RAVIART-THOMAS FLUX UNKNOWNS IN GROUP,I4,1H:/(1P,12E12.4))') &
      & IG,FUNKNO(:IELEM,IG)
      WRITE(6,'(48H BRERTD: RAVIART-THOMAS BOUNDARY FLUXES IN GROUP,I4,1H:/(1P,12E12.4))') &
      & IG,FHOMM(IG),FHOMP(IG)
    ENDIF
  ENDDO
  DEALLOCATE(FUNKNO)
END SUBROUTINE BRERTD