diff options
| author | stainer_t <thomas.stainer@oecd-nea.org> | 2025-09-08 13:48:49 +0200 |
|---|---|---|
| committer | stainer_t <thomas.stainer@oecd-nea.org> | 2025-09-08 13:48:49 +0200 |
| commit | 7dfcc480ba1e19bd3232349fc733caef94034292 (patch) | |
| tree | 03ee104eb8846d5cc1a981d267687a729185d3f3 /Trivac/src/NSSDRV.f | |
Initial commit from Polytechnique Montreal
Diffstat (limited to 'Trivac/src/NSSDRV.f')
| -rwxr-xr-x | Trivac/src/NSSDRV.f | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/Trivac/src/NSSDRV.f b/Trivac/src/NSSDRV.f new file mode 100755 index 0000000..4504051 --- /dev/null +++ b/Trivac/src/NSSDRV.f @@ -0,0 +1,343 @@ +*DECK NSSDRV + SUBROUTINE NSSDRV(IPTRK,IPMAC,IPFLX,ICHX,IDIM,NUN,NG,NEL,NMIX, + 1 ITRIAL,ICL1,ICL2,NADI,EPSNOD,MAXNOD,EPSTHR,MAXTHR,EPSOUT,MAXOUT, + 2 LNODF,BNDTL,NPASS,BB2,IPRINT) +* +*----------------------------------------------------------------------- +* +*Purpose: +* Driver for the flux calculation with the nodal expansion method. +* +*Copyright: +* Copyright (C) 2021 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 +* IPTRK nodal tracking. +* IPMAC nodal macrolib. +* IPFLX nodal flux. +* ICHX solution flag (=4.:CMFD; =5: NEM; =6: ANM). +* IDIM number of dimensions (1, 2 or 3). +* NUN number of unknowns per energy group. +* NG number of energy groups. +* NEL number of nodes in the nodal calculation. +* NMIX number of mixtures in the nodal calculation. +* ITRIAL type of expansion functions in the nodal calculation +* (=1: polynomial; =2: hyperbolic). +* ICL1 number of free iterations in one cycle of the inverse power +* method (used for thermal iterations). +* ICL2 number of accelerated iterations in one cycle. +* NADI number of inner ADI iterations. +* EPSNOD nodal correction epsilon. +* MAXNOD maximum number of nodal correction iterations. +* EPSTHR thermal iteration epsilon. +* MAXTHR maximum number of thermal iterations. +* EPSOUT convergence epsilon for the power method. +* MAXOUT maximum number of iterations for the power method. +* LNODF flag set to .true. to force discontinuity factors to one. +* BNDTL set to 'flat', 'linear' or 'quadratic' in 2D cases. +* BB2 imposed leakage used in non-regression tests. +* NPASS number of transverse current iterations. +* IPRINT edition flag. +* +*----------------------------------------------------------------------- +* + USE GANLIB +*---- +* SUBROUTINE ARGUMENTS +*---- + TYPE(C_PTR) IPTRK,IPMAC,IPFLX + INTEGER ICHX,IDIM,NUN,NG,NEL,NMIX,ITRIAL(NMIX,NG),ICL1,ICL2, + > MAXNOD,NADI,MAXTHR,MAXOUT,NPASS,IPRINT + REAL EPSNOD,EPSTHR,EPSOUT,BB2 + LOGICAL LNODF + CHARACTER*12 BNDTL +*---- +* LOCAL VARIABLES +*---- + PARAMETER (NSTATE=40) + INTEGER ISTATE(NSTATE),ICODE(6) + TYPE(C_PTR) JPMAC,KPMAC + CHARACTER HSMG*131 + CHARACTER(LEN=8) HADF(6) + CHARACTER(LEN=72) TITLE +*---- +* ALLOCATABLE ARRAYS +*---- + INTEGER, ALLOCATABLE, DIMENSION(:) :: MAT,IJJ,NJJ,IPOS,IDL,MUX, + 1 MUY,MUZ,IMAX,IMAY,IMAZ,IPY,IPZ + INTEGER, ALLOCATABLE, DIMENSION(:,:) :: KN,IQFR + REAL, ALLOCATABLE, DIMENSION(:) :: XX,YY,ZZ,XXX,YYY,ZZZ,WORK,VOL + REAL, ALLOCATABLE, DIMENSION(:,:) :: DIFF,SIGR,CHI,SIGF,QFR,ALBP, + 1 GAR2,GAR3 + REAL, ALLOCATABLE, DIMENSION(:,:,:) :: BETA,SCAT,FDXM,FDXP,GAR4 + REAL, ALLOCATABLE, DIMENSION(:,:,:,:) :: FD +*---- +* SCRATCH STORAGE ALLOCATION +*---- + ALLOCATE(MAT(NEL),IDL(NEL),KN(6,NEL),IQFR(6,NEL)) + ALLOCATE(XX(NEL),YY(NEL),ZZ(NEL),VOL(NEL),DIFF(NMIX,NG), + 1 SIGR(NMIX,NG),CHI(NMIX,NG),SIGF(NMIX,NG),SCAT(NMIX,NG,NG), + 2 QFR(6,NEL),FD(NMIX,2*IDIM,NG,NG)) +*---- +* RECOVER TRACKING INFORMATION +*---- + TITLE=' ' + CALL LCMLEN(IPTRK,'TITLE',LENGT,ITYLCM) + IF(LENGT.GT.0) THEN + CALL LCMGTC(IPTRK,'TITLE',72,TITLE) + IF(IPRINT.GT.0) WRITE(6,'(/9H NSSDRV: ,A72)') TITLE + ENDIF + CALL LCMGET(IPTRK,'STATE-VECTOR',ISTATE) + NX=ISTATE(14) + NY=ISTATE(15) + NZ=ISTATE(16) + LL4F=ISTATE(25) + LL4X=ISTATE(27) + LL4Y=ISTATE(28) + LL4Z=ISTATE(29) + ALLOCATE(MUX(LL4F),MUY(LL4F),MUZ(LL4F),IMAX(LL4F),IMAY(LL4F), + 1 IMAZ(LL4F),IPY(LL4F),IPZ(LL4F)) + CALL LCMGET(IPTRK,'ICODE',ICODE) + CALL LCMGET(IPTRK,'MATCOD',MAT) + CALL LCMGET(IPTRK,'KEYFLX',IDL) + CALL LCMGET(IPTRK,'VOLUME',VOL) + CALL LCMGET(IPTRK,'XX',XX) + CALL LCMGET(IPTRK,'KN',KN) + IF(IDIM.GE.2) CALL LCMGET(IPTRK,'YY',YY) + IF(IDIM.EQ.3) CALL LCMGET(IPTRK,'ZZ',ZZ) + CALL LCMGET(IPTRK,'QFR',QFR) + CALL LCMGET(IPTRK,'IQFR',IQFR) + ALLOCATE(XXX(NX+1),YYY(NY+1),ZZZ(NZ+1)) + CALL LCMGET(IPTRK,'XXX',XXX) + CALL LCMGET(IPTRK,'MUX',MUX) + CALL LCMGET(IPTRK,'IMAX',IMAX) + IF(IDIM.GE.2) THEN + CALL LCMGET(IPTRK,'YYY',YYY) + CALL LCMGET(IPTRK,'MUY',MUY) + CALL LCMGET(IPTRK,'IMAY',IMAY) + CALL LCMGET(IPTRK,'IPY',IPY) + ENDIF + IF(IDIM.EQ.3) THEN + CALL LCMGET(IPTRK,'ZZZ',ZZZ) + CALL LCMGET(IPTRK,'MUZ',MUZ) + CALL LCMGET(IPTRK,'IMAZ',IMAZ) + CALL LCMGET(IPTRK,'IPZ',IPZ) + ENDIF +*---- +* RECOVER MACROLIB INFORMATION +*---- + IF(BB2.NE.0.0) THEN + IF(IPRINT.GT.0) WRITE(6,'(/32H NSSDRV: INCLUDE LEAKAGE IN THE , + > 13HMACROLIB (B2=,1P,E12.5,2H).)') BB2 + ENDIF + CALL LCMGET(IPMAC,'STATE-VECTOR',ISTATE) + NALB=ISTATE(8) ! number of physical albedos + JPMAC=LCMGID(IPMAC,'GROUP') + ALLOCATE(WORK(NMIX*NG),IJJ(NMIX),NJJ(NMIX),IPOS(NMIX)) + DO IGR=1,NG + KPMAC=LCMGIL(JPMAC,IGR) + CALL LCMGET(KPMAC,'NTOT0',SIGR(1,IGR)) + CALL LCMGET(KPMAC,'DIFF',DIFF(1,IGR)) + CALL LCMGET(KPMAC,'CHI',CHI(1,IGR)) + CALL LCMGET(KPMAC,'NUSIGF',SIGF(1,IGR)) + CALL LCMGET(KPMAC,'IJJS00',IJJ) + CALL LCMGET(KPMAC,'NJJS00',NJJ) + CALL LCMGET(KPMAC,'IPOS00',IPOS) + CALL LCMGET(KPMAC,'SCAT00',WORK) + DO IBM=1,NMIX + SCAT(IBM,IGR,:)=0.0 + IPOSDE=IPOS(IBM)-1 + DO JGR=IJJ(IBM),IJJ(IBM)-NJJ(IBM)+1,-1 + IPOSDE=IPOSDE+1 + IF(IPOSDE.GT.NMIX*NG) CALL XABORT('NSSDRV: SCAT OVERFLOW.') + SCAT(IBM,IGR,JGR)=WORK(IPOSDE) ! IGR <-- JGR + ENDDO + SIGR(IBM,IGR)=SIGR(IBM,IGR)-SCAT(IBM,IGR,IGR) + ENDDO + IF(BB2.NE.0.0) THEN + DO IBM=1,NMIX + SIGR(IBM,IGR)=SIGR(IBM,IGR)+BB2*DIFF(IBM,IGR) + ENDDO + ENDIF + DO IBM=1,NMIX + IF(SIGR(IBM,IGR).LE.0.0) CALL XABORT('NSSDRV: SIGR<=0.') + ENDDO + ENDDO + DEALLOCATE(IPOS,NJJ,IJJ,WORK) + ALLOCATE(FDXM(NMIX,NG,NG),FDXP(NMIX,NG,NG),BETA(NALB,NG,NG), + > GAR2(NMIX,NG),GAR3(NMIX,NG),GAR4(NMIX,NG,NG)) + IF(NALB.GT.0) THEN + CALL LCMLEN(IPMAC,'ALBEDO',ILONG,ITYLCM) + IF(ILONG.EQ.NALB*NG) THEN + ALLOCATE(ALBP(NALB,NG)) + CALL LCMGET(IPMAC,'ALBEDO',ALBP) + BETA(:,:,:)=1.0 + DO IGR=1,NG + BETA(:NALB,IGR,IGR)=ALBP(:NALB,IGR) + ENDDO + DEALLOCATE(ALBP) + ELSE IF(ILONG.EQ.NALB*NG*NG) THEN + CALL LCMGET(IPMAC,'ALBEDO',BETA) + ELSE + CALL XABORT('NSSDRV: INVALID ALBEDO LENGTH.') + ENDIF + IF(IPRINT.GT.1) THEN + DO IALB=1,NALB + WRITE(6,'(/35H NSSDRV: PHYSICAL ALBEDO MATRIX ID=,I4)') IALB + DO IGR=1,NG + WRITE(6,'(5X,1P,10E12.4)') BETA(IALB,IGR,:) + ENDDO + ENDDO + ENDIF + ENDIF + FD(:,:,:,:)=0.0 + IF(LNODF.OR.ISTATE(12).EQ.0) THEN + DO IGR=1,NG + FD(:NMIX,:2*IDIM,IGR,IGR)=1.0 + ENDDO + ELSE IF(ISTATE(12).EQ.2) then + CALL LCMSIX(IPMAC,'ADF',1) + CALL LCMGET(IPMAC,'NTYPE',NSURFD) + CALL LCMGET(IPMAC,'AVG_FLUX',GAR3) + CALL LCMGTC(IPMAC,'HADF',8,NSURFD,HADF) + IF(NSURFD.EQ.1) THEN + CALL LCMGET(IPMAC,HADF(1),GAR2) + DO IBM=1,NMIX + DO IGR=1,NG + FD(IBM,:2*IDIM,IGR,IGR)=GAR2(IBM,IGR)/GAR3(IBM,IGR) + ENDDO + ENDDO + ELSE IF(NSURFD.EQ.2*IDIM) THEN + DO I=1,NSURFD + IF(HADF(I)(1:3).NE.'FD_') THEN + WRITE(HSMG,'(7HNSSDRV:,A,28H FOUND; FD_ PREFIX EXPECTED.) + 1 ') TRIM(HADF(I)) + CALL XABORT(HSMG) + ENDIF + CALL LCMGET(IPMAC,HADF(I),GAR2) + DO IGR=1,NG + FD(:NMIX,I,IGR,IGR)=GAR2(:NMIX,IGR)/GAR3(:NMIX,IGR) + ENDDO + ENDDO + ELSE + WRITE(HSMG,'(12HNSSDRV: 1 OR,I3,25HDISCONTINUITY FACTORS EXP, + 1 6HECTED.)') 2*IDIM + CALL XABORT(HSMG) + ENDIF + CALL LCMSIX(IPMAC,' ',2) + ELSE IF(ISTATE(12).EQ.3) THEN + CALL LCMSIX(IPMAC,'ADF',1) + CALL LCMGET(IPMAC,'NTYPE',NSURFD) + CALL LCMGTC(IPMAC,'HADF',8,NSURFD,HADF) + IF(NSURFD.EQ.1) THEN + CALL LCMGET(IPMAC,HADF(1),GAR2) + DO IBM=1,NMIX + DO IGR=1,NG + FD(IBM,:2*IDIM,IGR,IGR)=GAR2(IBM,IGR) + ENDDO + ENDDO + ELSE IF(NSURFD.EQ.2*IDIM) THEN + DO I=1,NSURFD + IF(HADF(I)(1:3).NE.'FD_') THEN + WRITE(HSMG,'(7HNSSDRV:,A,28H FOUND; FD_ PREFIX EXPECTED.) + 1 ') TRIM(HADF(I)) + CALL XABORT(HSMG) + ENDIF + CALL LCMGET(IPMAC,HADF(I),GAR2) + DO IGR=1,NG + FD(:NMIX,I,IGR,IGR)=GAR2(:NMIX,IGR) + ENDDO + ENDDO + ELSE + WRITE(HSMG,'(12HNSSDRV: 1 OR,I3,25HDISCONTINUITY FACTORS EXP, + 1 6HECTED.)') 2*IDIM + CALL XABORT(HSMG) + ENDIF + CALL LCMSIX(IPMAC,' ',2) + ELSE IF(ISTATE(12).EQ.4) THEN + ! matrix discontinuity factors + CALL LCMSIX(IPMAC,'ADF',1) + CALL LCMGET(IPMAC,'NTYPE',NSURFD) + IF(NSURFD.NE.2*IDIM) THEN + WRITE(HSMG,'(7HNSSDRV:,I3,30HDISCONTINUITY FACTORS EXPECTED)' + 1 ) 2*IDIM + CALL XABORT(HSMG) + ENDIF + CALL LCMGTC(IPMAC,'HADF',8,NSURFD,HADF) + DO I=1,NSURFD + IF((HADF(I)(1:4).NE.'ERM_').AND.(HADF(I)(1:3).NE.'FD_')) THEN + WRITE(HSMG,'(7HNSSDRV:,A,30H FOUND; ERM_ OR FD_ PREFIX EXP, + 1 6HECTED.)') TRIM(HADF(I)) + CALL XABORT(HSMG) + ENDIF + CALL LCMGET(IPMAC,HADF(I),GAR4) + DO JGR=1,NG + DO IGR=1,NG + FD(:NMIX,I,IGR,JGR)=GAR4(:NMIX,IGR,JGR) + ENDDO + ENDDO + ENDDO + CALL LCMSIX(IPMAC,' ',2) + ELSE + WRITE(6,'(13H NSSDRV: IDF=,I3)') ISTATE(12) + CALL XABORT('NSSDRV: FLUX/CURRENT INFORMATION NOT SUPPORTED.') + ENDIF + IF(IPRINT.GT.3) THEN + DO I=1,NSURFD + WRITE(6,'(/31H NSSDRV: discontinuity factors ,A8)') HADF(I) + DO IBM=1,NMIX + DO IGR=1,NG + WRITE(6,'(4H FD(,2I4,2H)=,1p,12E12.4/(8X,12E12.4))') + 1 IBM,IGR,FD(IBM,:,IGR,IGR) + ENDDO + ENDDO + ENDDO + ENDIF + DEALLOCATE(GAR4,GAR3,GAR2,FDXP,FDXM) +*---- +* COMPUTE THE FLUX AND STORE NODAL SOLUTION IN IPFLX +*---- + IF(ICHX.EQ.5) THEN ! NEM + CALL NSSFL1(IPFLX,NUN,NG,NEL,NMIX,NALB,ITRIAL,EPSOUT,MAXOUT, + 1 MAT,XX,IQFR,QFR,DIFF,SIGR,CHI,SIGF,SCAT,BETA,FD,IPRINT) + ELSE IF(ICHX.EQ.4) THEN ! CMFD + CALL NSSFL2(IPFLX,NUN,NG,NEL,NMIX,NALB,EPSOUT,MAXOUT,MAT,XX, + 1 IQFR,QFR,DIFF,SIGR,CHI,SIGF,SCAT,BETA,FD,IPRINT) + ELSE IF((ICHX.EQ.6).AND.(IDIM.EQ.1)) THEN ! ANM-1D + CALL NSSFL3(IPFLX,NUN,NG,NEL,NMIX,NALB,EPSNOD,MAXNOD,EPSOUT, + 1 MAXOUT,MAT,XX,XXX,IDL,IQFR,QFR,DIFF,SIGR,CHI,SIGF,SCAT,BETA, + 2 FD,IPRINT) + ELSE IF((ICHX.EQ.6).AND.(IDIM.EQ.2)) THEN ! ANM-2D + CALL NSSFL4(IPFLX,NUN,NG,NX,NY,LL4F,LL4X,LL4Y,NMIX,NALB,ICL1, + 1 ICL2,NADI,EPSNOD,MAXNOD,EPSTHR,MAXTHR,EPSOUT,MAXOUT,MAT,XX,YY, + 2 XXX,YYY,IDL,VOL,KN,IQFR,QFR,DIFF,SIGR,CHI,SIGF,SCAT,BETA,FD, + 3 BNDTL,NPASS,MUX,MUY,IMAX,IMAY,IPY,IPRINT) + ELSE IF((ICHX.EQ.6).AND.(IDIM.EQ.3)) THEN ! ANM-3D + CALL NSSFL5(IPFLX,NUN,NG,NX,NY,NZ,LL4F,LL4X,LL4Y,LL4Z,NMIX,NALB, + 1 ICL1,ICL2,NADI,EPSNOD,MAXNOD,EPSTHR,MAXTHR,EPSOUT,MAXOUT,MAT,XX, + 2 YY,ZZ,XXX,YYY,ZZZ,IDL,VOL,KN,IQFR,QFR,DIFF,SIGR,CHI,SIGF,SCAT, + 3 BETA,FD,BNDTL,NPASS,MUX,MUY,MUZ,IMAX,IMAY,IMAZ,IPY,IPZ,IPRINT) + ELSE + CALL XABORT('NSSDRV: OPTION NOT AVAILABLE.') + ENDIF + ISTATE(:)=0 + ISTATE(1)=NG + ISTATE(2)=NUN + ISTATE(6)=2 + CALL LCMPUT(IPFLX,'STATE-VECTOR',NSTATE,1,ISTATE) +*---- +* SCRATCH STORAGE DEALLOCATION +*---- + DEALLOCATE(IPZ,IPY,IMAZ,IMAY,IMAX,MUZ,MUY,MUX) + DEALLOCATE(BETA) + DEALLOCATE(ZZZ,YYY,XXX) + DEALLOCATE(FD,QFR,SCAT,SIGF,CHI,SIGR,DIFF,VOL,ZZ,YY,XX) + DEALLOCATE(IQFR,KN,IDL,MAT) + RETURN + END |
