c
c
C File name ............. GXHOCS.FOR ....................... 110817
C File includes the following subroutines and functions:
C GXHOCS, GXHOEN, GXHOHL, BLKSLD, GXFLPS
C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
C
c
SUBROUTINE GXHOCS
C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
C SUBROUTINE GXHOCS introduces
c
c higher-order convection schemes for
C use with the staggered-mesh option in PHOENICS. These are
C discretization schemes for the convection terms which have
C truncation errors of order greater than one (i.e. higher than
C First-Order Upwind). These schemes allow more accurate resolution
C of convection-dominated flows, especially when these contain
C gradients of the flow variables which are not aligned with the
C grid directions (e.g. recirculating flows).
C
C Two classes of schemes have been implemented:
C
C LINEAR SCHEMES: - These include the Central-Differencing scheme
C (CDS), the Linear-Upwind scheme (LUS), the Quadratic-Upwind
C scheme (QUICK), the Cubic-Upwind scheme (CUS) and Fromm's scheme.
C These offer generally good resolution, but do not guarantee
C boundedness and may therefore be prone to spurious oscillations
C such as "wiggles" around shock waves or negative values of KE or
C EP.
C
C NON-LINEAR FLUX-LIMITED SCHEMES: - These schemes also offer
C improved resolution but are designed to limit the higher-order
C correction so as to guarantee positive coefficients and therefore
C bounded behaviour. This limiting may reduce the accuracy of the
C discretization to some extent. These schemes modify themselves
C according to the local flow conditions and are therefore also
C termed "non-linear". The flux limiters that have been implemented
C are:
C SMART (bounded QUICK)
C Koren (bounded CUS, TVD)
C MUSCL (van Leer: bounded Fromm, TVD)
C HQUICK (based on QUICK, smooth/harmonic)
C OSPRE (smooth/continuous)
C van Leer harmonic (smooth/harmonic, TVD)
C van Albada (smooth/continuous)
C Minmod (= Zhu/Rodi SOUCUP scheme, TVD)
C Superbee (compressive limiter for sharp gradients, TVD)
C UMIST (bounded QUICK, TVD )
C HCUS (based on CUS, smooth/harmonic)
C CHARM (based on QUICK and UDS, polymonial ratio)
C
C These two classes, as implemented, offer a choice of 17
C different schemes, though not all of these are in fact recom-
C mended for general use. Those recommended are:
C
C (i) Linear: either CUS or QUICK. LUS is less accurate, but much
C more stable.
C
C (ii) Non-linear: SMART and Koren give good accuracy with strong
C relaxation. MUSCL and H-QUICK are less accurate but more
C stable. OSPRE is the most stable but again a little less
C accurate. van Leer harmonic, van Albada, Minmod and Superbee
C are classical limiters that are included for completeness.
C
C GXHOCS is called from Group 1, Sections 1 and 2, and also from
C Group 13 of GREX3:
C
C ISC=13 Section 13 : COVAL(HOCS,PHI,FIXFLU,GRND1)
C Linear - KAPPA schemes
C
C ISC=14 Section 14 : COVAL(HOCS,PHI,FIXFLU,GRND2)
C Non-Linear - Flux-Limited Positive schemes
C
C The integer array INLCS(1) in GXHOCS contains the scheme number
C for each variable PHI. The LINEAR schemes available are:
C INLCS(phi) = 1 -> LUS = 2 -> FROMM = 3 -> CUS
C = 4 -> QUICK = 5 -> CDS
C The NON-LINEAR schemes available are:
C INLCS(phi) = 6 -> SMART = 7 -> KOREN = 8 -> MUSCL
C = 9 -> H-QUICK = 10 -> OSPRE
C = 11 -> VAN LEER HARMONIC/HLPA
C = 12 -> VAN ALBADA = 13 -> MINMOD/SOUCUP
C = 14 -> SUPERBEE = 15 -> UMIST
C = 16 -> H-CUS = 17 -> CHARM
C
C Q1-file activation:
C
C A particular scheme is assigned to one or more dependent variables
C by the SCHEME command, whose syntax is:
C
C SCHEME(NAME,variable name 1,variable name 2,...etc.)
C
C The first argument NAME identifies the required discretisation
C scheme, as follows:
C NAME = LUS, FROMM, CUS, QUICK, CDS, SMART, KOREN, MUSCL, HQUICK,
C OSPRE, VANLH, VANALB, MINMOD, SUPBEE, UMIST, HCUS or CHARM.
C
C The second argument permits the user to specify those SOLVEd
C variables which will use the selected scheme. If ALL is entered as
C the second argument, then the selected scheme is applied to all
C SOLVEd-for variables. For example,
C
C SCHEME(QUICK,U1,V1);SCHEME(SMART,H1,C1,C2)
C
C selects QUICK for U1 and V1, and SMART for H1,C1 and C2, and
C Upstream differencing (as DIFCUT=0) for any SOLVEd variables which
C do not appear in a SCHEME command. The INLCS array is determined
C by the SCHEME command, and then transmitted to GXHOCS via the
C SPEDAT facility. The schemes may also be activated via the MENU.
C
C The schemes are described under the Encyclopaedia entry 'SCHEMES
C FOR CONVECTION DISCRETISATION' ( see also the HELP entry for the PIL
C command SCHEME ).
C
C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
C
INCLUDE 'patcmn'
INCLUDE 'farray'
INCLUDE 'satear'
COMMON /IDA10/ INLCS(150)
COMMON /LB/ LB1(16),LZDZ,LB2(8),LZDZG,LB3(3),DXU2D,DYV2D,
1 LB4(8),DXG2D,DYG2D,LB5(96),LRHO1,LRHO1H,LB6,
1 LRHO2,LRHO2H,LB7(3),AEAST,ANORTH,AHIGH,LB8(46),
1 LCEA,LCNA,LCHA,LCEA2,LCNA2,LCHA2,LB9(58),CON1E,
1 CON2E,CON1N,CON2N,CON1H,CON2H,LB10(36)
1 /GENI/ NXNY,IGN1(8),NFM,IGN2(38),NPHI4,IGN3(11)
1 /IGE/ IXF,IXL,IYF,IYL,IGE1(2),IGR,ISC,IRUN,IZ,
1 IGE2,ISWEEP,ISTEP,INDVAR,VAL,IGE4(10)
1 /CGE/ NPATCH
1 /BFCIN1/ L0B(106),LULAST
1 /BFCINT/ APROJE,APROJN,APROJH,IBFC1(7),DHXPE,IBFC2,DHYPN,
1 IBFC3,DHZPH,IBFC4(12),DZGPH,IBFC5(39),XP,YP,ZP,
1 IBFC6(36)
1 /GHOCS/ L0PHI,L0VAL,L0RUA,L0RHO,L0RHOH,L0R,L0FPR,L0PRP,
1 L0CVL,L0UCT,L0VCT,L0WCT,L0XP,L0YP,L0ZP,L0DXG,
1 L0DYG,L0DZG,KAPP(150),KAPM(150),U1ORU2,V1ORV2,
1 W1ORW2,UVW,STACON,ISCHEM,DEBHOC,debhcs
1 /IZLIM/ IZF,IZL
1 /RSG/ RGFIL1(19),RSG20,RGFIL2(180)
1 /ISG/ ISGF1(57),ISCHM1,ISGF2(42)
COMMON/LMAIN2/ DBFIL1,DBGSWP,DBGTZ,DBFIL2(8)
COMMON/BFICRT/ ICRT(6),IUCMP(2),IVCMP(2),IWCMP(2)
COMMON /NAMFN/ NAMFUN,NAMSUB
COMMON/MDFCNV/LIMCNV ! convection was modified by in-form
LOGICAL LIMCNV
C
CHARACTER NPATCH*8,NAMFUN*6,NAMSUB*6,CTEMP*8
logical debhcs,debhoc,dbgswp,dbgtz,dbfil1,dbfil2
LOGICAL INIRUA,U1ORU2,V1ORV2,W1ORW2,UVW,FLUID1,STACON,SOLVE
INTEGER VAL,AEAST,ANORTH,AHIGH,APROJN,
1 APROJH,DXU2D,DYV2D,DXG2D,DYG2D,DHXPE,DHYPN,DHZPH,DZGPH,
1 CON1E,CON1N,CON1H,CON2E,CON2N,CON2H,APROJE,XP,YP,ZP
REAL KAPP,KAPM,KAPPA
CHARACTER*6 SCNAM(17)
DATA SCNAM /'LUS', 'FROMM', 'CUS', 'QUICK',
1 'CDS', 'SMART', 'KOREN', 'VANL1',
1 'HQUICK', 'OSPRE', 'VANL2', 'VANALB',
1 'MINMOD', 'SUPBEE', 'UMIST', 'HCUS',
1 'CHARM'/
SAVE INIRUA
C
C+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
NAMSUB='GXHOCS'
C
IF(IGR==1 .AND. ISC==1) THEN
C
C>>>>>>>>>>>>>>>>>>>>> Group 1 ------- Section 1 <<<<<<<<<<<<<<<<<<<<<
C
C.... Construct INLCS array from SPEDAT facility & then set parameter
C values for KAPPA schemes.
if(.not.nullpr) WRITE(LUPR1,101)
101 FORMAT(2X,'NO',3X,'VARIABLE',4X,'SCHEME')
ONED3=1./3.
DO MPHI=1,NPHI
INLCS(MPHI)=0
IF(MPHI>2 .AND. SOLVE(MPHI)) THEN
WRITE(CTEMP,'(I3.3)') MPHI
CALL GETSDI('SCHEME','INLCS'//CTEMP,INLCS(MPHI))
IF(INLCS(MPHI)/=0) THEN
IF(.NOT.NULLPR) WRITE(LUPR1,102)
1 MPHI,NAME(MPHI),SCNAM(INLCS(MPHI))
ELSE
CYCLE
ENDIF
IF(INLCS(MPHI)<6.OR.INLCS(MPHI)==10.OR.
1 INLCS(MPHI)==12) THEN
IF(.NOT.NULLPR) THEN
CALL WRIT40('Scheme '//SCNAM(INLCS(MPHI)))
CALL WRIT40('Use of this scheme is not recommended')
CALL WRIT40('See PHOENICS Encyclopaedia entry on ')
CALL WRIT40('"Schemes of discretization" ')
ENDIF
ENDIF
IF(INLCS(MPHI)==1) THEN
KAPPA=-1.
ELSEIF(INLCS(MPHI)==2) THEN
KAPPA=0.
ELSEIF(INLCS(MPHI)==3) THEN
KAPPA=ONED3
ELSEIF(INLCS(MPHI)==4) THEN
KAPPA=0.5
ELSEIF(INLCS(MPHI)==5) THEN
KAPPA=1.
ENDIF
IF(INLCS(MPHI)>=1.AND.INLCS(MPHI)<=5) THEN
KAPP(MPHI) = 0.5*(1.0 + KAPPA)
KAPM(MPHI) = 0.5*(1.0 - KAPPA)
ELSE
KAPP(MPHI) = 0.
KAPM(MPHI) = 0.
ENDIF
ENDIF
ENDDO
IF(ISCHM1>1) THEN
WRITE(LUPR1,'('' Schemes become active after sweep '',I6)')
1 ISCHM1
ELSE
WRITE(LUPR1,'('' Schemes are active for all sweeps '')')
ENDIF
CALL WRITST
102 FORMAT(1X,I3,5X,A4,5X,A6)
C
C.... STACON=T signifies that in-line convections for velocity
C will be computed by averaging scalar convection fluxes.
STACON=UCONV.AND.NAMGRD=='CONV'
CALL GETSDL('SCHEME','DEBHOC',DEBHOC)
ELSEIF(IGR==13) THEN
C
C>>>>>>>>>>>>>>>>>>>>> Group 13 ------- Section 13-14 <<<<<<<<<<<<<<<<
C
IF(NPATCH(1:4)/='HOCS') RETURN
C
ISCHEM=INLCS(INDVAR)
STACON = STACON.OR.LIMCNV
debhcs=debhoc.and.dbgswp.and.dbgtz.and.dbgphi(indvar)
C.... Initialize values of source term to zero on slab
CALL FN1(VAL,0.0)
IF(STEADY.AND.FIINIT(1)/=READFI) THEN ! always active for transient & restart
IF(ISWEEP1) L0RHOH = L0F(LRHO1H)
IF(.NOT.ONEPHS) L0R = L0F(9)
ELSE
L0RHO = L0F(DEN2)
IF(NZ>1) L0RHOH = L0F(LRHO2H)
IF(.NOT.ONEPHS) L0R = L0F(10)
ENDIF
C.... Set cell-geometry addresses
IF(NX>1) THEN
L0DXU=L0F(DXU2D); L0DXG=L0F(DXG2D); L0AE=L0F(AEAST)
IF(BFC) L0DXU = L0B(DHXPE)+IZNXNY
ENDIF
IF(NY>1) THEN
L0DYV=L0F(DYV2D); L0DYG=L0F(DYG2D); L0AN=L0F(ANORTH)
IF(BFC) L0DYV = L0B(DHYPN)+IZNXNY
ENDIF
IF(NZ>1) THEN
IF(.NOT.BFC) THEN
L0AH = L0F(AHIGH)
L0DZW=L0F(LZDZ); L0DZG=L0F(LZDZG)
ELSE
L0AH = L0B(APROJH)+IZNXNY
L0DZG = L0B(DZGPH)+IZNXNY
L0DZW = L0B(DHZPH)+IZNXNY
ENDIF
ENDIF
C
C.... N.B. Distance of cell centre from cell face in covariant
C components is not available: DHXPE etc. are NORMAL to cell faces.
C (DHXPE,DHYPN,DHZPH are accessed here but not used.)
C Hence in BFC case it is assumed faces are midway between centres.
IF(BFC) THEN
L0DXU=L0DXG; L0DYV=L0DYG; L0DZW=L0DZG
ENDIF
C
C.... Set offset indices for 1st/2nd-phase velocities and mass fluxes
IF(FLUID1(INDVAR)) THEN
IADD = 0; IAD2 = 0
ELSE
IADD = 1; IAD2 = 6
ENDIF
C.... Store original PATCH limits
C (Limits IZF,IZL are not defined and hence GETPTC required)
CALL GETPTC(NPATCH,PATYP,IXF,IXL,IYF,IYL,IZF,IZL,ITF,ITL)
IXFP=IXF; IXLP=IXL; IYFP=IYF; IYLP=IYL; IZFP=IZF; IZLP=IZL
C
C.... Check for momentum variables and reset patch limits appropriately
U1ORU2=.FALSE.
V1ORV2=.FALSE.
W1ORW2=.FALSE.
IF(INDVAR==3.OR.INDVAR==4) THEN
U1ORU2=.TRUE.
IXL = MIN(IXL,(NX-1))
ELSEIF(INDVAR==5.OR.INDVAR==6) THEN
V1ORV2=.TRUE.
IYL = MIN(IYL,(NY-1))
ELSEIF(INDVAR==7.OR.INDVAR==8) THEN
W1ORW2=.TRUE.
IZL = MIN(IZL,(NZ-1))
ENDIF
UVW = U1ORU2.OR.V1ORV2.OR.W1ORW2
IF(BFC.AND.UVW) THEN
IF(FLUID1(INDVAR)) THEN
IF(NX>1) JUCMP = IUCMP(1)
IF(NY>1) JVCMP = IVCMP(1)
IF(NZ>1) JWCMP = IWCMP(1)
IUCRT=ICRT(1); IVCRT=ICRT(3); IWCRT=ICRT(5)
ELSE
IF(NX>1) JUCMP = IUCMP(2)
IF(NY>1) JVCMP = IVCMP(2)
IF(NZ>1) JWCMP = IWCMP(2)
IUCRT=ICRT(2); IVCRT=ICRT(4); IWCRT=ICRT(6)
ENDIF
L0UCT=L0F(IUCRT); L0VCT=L0F(IVCRT); L0WCT=L0F(IWCRT)
L0XP=L0B(XP); L0YP=L0B(YP); L0ZP=L0B(ZP)
L0XP = L0XP + IZNXNY
L0YP = L0YP + IZNXNY
L0ZP = L0ZP + IZNXNY
ENDIF
C
INIRUA=(STEADY.AND.ISWEEP==FSWEEP).OR.(.NOT.STEADY.AND.
1 ISTEP==FSTEP.AND.ISWEEP==FSWEEP)
C... NORTH cell-face contribution to HOCS source term
IF(NY>1) THEN
IF(.NOT.(BFC.AND.UVW)) THEN
L0CVL = L0F(5+IADD)
ELSE
L0CVL = L0F(JVCMP)
ENDIF
IF(FLUID1(INDVAR)) THEN
LCONN = ITWO(LCNA,CON1N,NZ==1)
L0RUA = L0F(LCONN) + IZNXNY
ELSE
LCONN = ITWO(LCNA2,CON2N,NZ==1)
L0RUA = L0F(LCONN) + IZNXNY
ENDIF
IF(INIRUA.AND.NZ>1.AND.W1ORW2) THEN
DO J=1,NXNY
F(L0RUA+NXNY+J)=0.0
ENDDO
ENDIF
IYF=IYF+1; IYL=IYL-2
CALL GXHOEN(ISC,L0DYG,L0DYV,L0AN,L0DXG,V1ORV2,U1ORU2,1,NY,1)
IYF=IYFP; IYL=IYLP
ENDIF
C
C... HIGH/LOW cell-face contribution to HOCS source term
IF(NZ>1) THEN
IF(BFC.AND.W1ORW2) THEN
L0CVL = L0F(JWCMP)
ELSE
L0CVL = L0F(7+IADD)
ENDIF
C.... HIGH face
C ---------
IF(FLUID1(INDVAR)) THEN
L0RUA = L0F(CON1H) + IZNXNY
ELSE
L0RUA = L0F(CON2H) + IZNXNY
ENDIF
IF(INIRUA.AND.NZ>1.AND.W1ORW2) THEN
DO J=1,NXNY
F(L0RUA+NXNY+J)=0.0
ENDDO
ENDIF
IF(IZ>=IZF+1 .AND. IZ<=IZL-2) THEN
CALL GXHOHL(5,ISC,L0DZW,L0DZG,L0AH)
ENDIF
C.... LOW face
C --------
IF(FLUID1(INDVAR)) THEN
L0RUA = L0F(CON1H) + (IZ-2)*NXNY
ELSE
L0RUA = L0F(CON2H) + (IZ-2)*NXNY
ENDIF
c L0CVL = L0CVL-NFM
c L0PHI = L0PHI-NFM
c IF(BFC)
c 1 CALL SUB3(L0UCT,L0UCT-NFM,L0VCT,L0VCT-NFM,L0WCT,L0WCT-NFM)
IF(IZ>=IZF+2 .AND. IZ<=IZL-1) THEN
L0CVL = L0CVL-NFM
L0PHI = L0PHI-NFM
IF(BFC) THEN
L0UCT=L0UCT-NFM; L0VCT=L0VCT-NFM; L0WCT=L0WCT-NFM
ENDIF
CALL GXHOHL(6,ISC,L0DZW,L0DZG,L0AH)
L0CVL = L0CVL+NFM
L0PHI = L0PHI+NFM
IF(BFC) THEN
L0UCT=L0UCT+NFM; L0VCT=L0VCT+NFM; L0WCT=L0WCT+NFM
ENDIF
ENDIF
IZF=IZFP; IZL=IZLP
ENDIF
C
C... EAST cell-face contribution to HOCS source term
IF(NX>1) THEN
IF(.NOT.(BFC.AND.UVW)) THEN
L0CVL = L0F(3+IADD)
ELSE
L0CVL = L0F(JUCMP)
ENDIF
IF(FLUID1(INDVAR)) THEN
LCONE = ITWO(LCEA,CON1E,NZ==1)
L0RUA = L0F(LCONE) + IZNXNY
ELSE
LCONE = ITWO(LCEA2,CON2E,NZ==1)
L0RUA = L0F(LCONE) + IZNXNY
ENDIF
IF(INIRUA.AND.NZ>1.AND.W1ORW2) THEN
DO J=1,NXNY
F(L0RUA+NXNY+J)=0.0
ENDDO
ENDIF
IXF=IXF+1; IXL=IXL-2
CALL GXHOEN(ISC,L0DXG,L0DXU,L0AE,L0DYG,U1ORU2,V1ORV2,NY,1,3)
IXF=IXFP; IXL=IXLP
ENDIF
ENDIF
NAMSUB='gxhocs'
END
C !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
c
SUBROUTINE GXHOEN(ISC,L0DG,L0DV,L0AF,L0DGN,UVI,UVN,INDI,INDN,IDIR)
C *********************************************************************
C Purpose: to calculate higher-order correction for EAST or NORTH
C faces on a single slab of cells
C east face north face
C Input: L0DG = L0DXG L0DYG
C L0DV = L0DXU L0DYV
C L0AF = L0AE L0AN
C L0DGN = L0DYG L0DXG
C UVI = U1ORU2 V1ORV2
C UVN = V1ORV2 U1ORU2
C INDI = NY 1
C INDN = 1 NY
C IDIR = 3 1
C Called by: GXHOCS
C *********************************************************************
INCLUDE 'farray'
COMMON
1 /IDATA/ NX,NY,NZ,LUPR1,IDAT1(116)
1 /LDATA/ CARTES,LD1(2),ONEPHS,LD2(3),XCYCLE,LD3(10),STEADY,
1 BFC,LD4(44),NONORT,LD5(19)
1 /IGE/ IXF,IXL,IYF,IYL,IGE1(5),IZ,
1 IGE3,ISWEEP,IGE4,INDVAR,IGE5(11)
1 /GENI/ NXNY,IGN1(8),NFM,IGN2(38),NPHI4,IGN3(11)
1 /GHOCS/ L0PHI,L0VAL,L0RUA,L0RHO,L0RHOH,L0R,L0FPR,L0PRP,
1 L0CVL,L0UCT,L0VCT,L0WCT,L0XP,L0YP,L0ZP,LBDXG,
1 LBDYG,LBDZG,KAPP(150),KAPM(150),U1ORU2,V1ORV2,
1 W1ORW2,UVW,STACON,ISCHEM,DEBHOC,debhcs
1 /NAMFN/ NAMFUN,NAMSUB
1 /RDATA/ TINY,RDAT(84)
C
logical debhoc,debhcs
LOGICAL BLKSLD,DOCOR,U1ORU2,V1ORV2,W1ORW2,CARTES,UVI,UVN,UVW,LD1,
1 XCYCLE,LD2,STEADY,BFC,LD3,LD4,LD5,NONORT,QGE,ONEPHS,
1 STACON
REAL KAPP,KAPM
CHARACTER*6 NAMFUN,NAMSUB
C
NAMSUB = 'GXHOEN'
C
C.... Cycle over the patch.
debhcs=.false.
if(debhcs) call banner(1,namsub,110817)
IZNXNY=(IZ-1)*NXNY
DO 10 IX=IXF,IXL
IADD = (IX-1)*NY
DO 10 IY=IYF,IYL
if(debhcs) call writ2i('ix ',ix,'iy ',iy)
IXY = IY+IADD
C.... Check for blocked faces or solid cells within stencil
DOCOR=.NOT.BLKSLD(UVI,UVN,W1ORW2,INDI,INDN,NXNY,IXY+IZNXNY,
1 IDIR)
if(debhcs) call writ1l('docor ',docor)
C.... If no blocked/solid cells/faces within stencil then continue
IF(DOCOR) THEN
C
C.... Set mass-flux coefficient for face
RUA = F(L0RUA+IXY)
if(debhcs) call writ3l('uvi ',uvi,'uvn ',uvn,
1 'stacon ',stacon)
IF(UVI) THEN
IF(STACON) THEN
RUA = 0.5*(RUA + F(L0RUA+IXY+INDI))
ELSE
IF(F(L0CVL+IXY)>0.0) THEN
GRO = F(L0RHO+IXY)
IF(.NOT.ONEPHS) GVF = F(L0R+IXY)
ELSE
GRO = F(L0RHO+IXY+INDI)
IF(.NOT.ONEPHS) GVF = F(L0R+IXY+INDI)
ENDIF
GUF = 0.5*(F(L0CVL+IXY) + F(L0CVL+IXY+INDI))
RUA = GRO*GUF*F(L0AF+IXY)
IF(.NOT.ONEPHS) RUA=RUA*GVF
ENDIF
ELSEIF(UVN) THEN
RUA = 0.5*(RUA + F(L0RUA+IXY+INDN))
ELSEIF(W1ORW2) THEN
C N109 fails because f(l0rua+ixy+nxny) has 1e19 on 1st sweep
c see mrm 06.05.05 initialise con1n & con1e for 1st sweep
RUA = 0.5*(RUA + F(L0RUA+IXY+NXNY))
ENDIF
C
C.... Values of convected variable on each side of face
FP = F(L0PHI+IXY)
FEN = F(L0PHI+IXY+INDI)
C
C.... Calculate required cell-geometry data
IF(UVI) THEN
DXC = F(L0DV+IXY+INDI)
if(dxc<=0.0) then
call writ3i('indvar ',indvar,'ix ',ix,
1 'iy ',iy)
CALL SET_ERR(444, 'Error. See reslt file.',1)
C stop
endif
IF(QGE(RUA,0.0)) THEN
DXU = F(L0DV+IXY)
GDX = 0.5*F(L0DV+IXY+INDI)
ELSE
DXU = F(L0DV+IXY+2*INDI)
GDX = -0.5*F(L0DV+IXY+INDI)
ENDIF
ELSE
DXC = F(L0DG+IXY)
IF(QGE(RUA,0.0)) THEN
DXU = F(L0DG+IXY-INDI)
GDX = 0.5*F(L0DV+IXY)
ELSE
DXU = F(L0DG+IXY+INDI)
GDX = -0.5*F(L0DV+IXY+INDI)
ENDIF
ENDIF
C
C.... Calculate gradients of convected variable
IF(.NOT.(BFC.AND.NONORT.AND.UVW)) THEN
C
GRPHC = (FEN - FP)/(DXC+tiny)
IF(QGE(RUA,0.0)) THEN
fpnei = F(L0PHI+IXY-INDI)
GRPHU = (FP - F(L0PHI+IXY-INDI))/(DXU+tiny)
ELSE
fpnei = F(L0PHI+IXY+2*INDI)
GRPHU = (F(L0PHI+IXY+2*INDI) - FEN)/(DXU+tiny)
ENDIF
C
ELSE
C
IF(UVI) THEN
INDB = INDI
DP = F(L0DG+IXY)
DE = F(L0DG+IXY+INDI)
if(debhcs) call writ2r('dp 1',dp,'de ',de)
ELSEIF(UVN) THEN
INDB = INDN
DP = F(L0DGN+IXY)
DE = F(L0DGN+IXY+INDI)
if(debhcs) then
call writ2r('dp 2',dp,'de ',de)
call writ3i('l0dgn ',l0dgn,'ixy ',ixy,
1 'indi ',indi)
endif
ELSE
INDB = NXNY
DP = F(LBDZG+IXY)
DE = F(LBDZG+IXY+INDI)
if(debhcs) call writ2r('dp 3',dp,'de ',de)
ENDIF
C
if(de<=0.0.or.dp<=0) then
call writ3i('indvar ',indvar,'ix ',ix,
1 'iy ',iy)
call writ2r('dp ',dp,'de ',de)
CALL SET_ERR(511, 'Error. See result file.',1)
C call wayout(1)
endif
DP=DP+TINY
DE=DE+TINY
DPX = (F(L0XP+IXY+INDB)-F(L0XP+IXY))/DP
DPY = (F(L0YP+IXY+INDB)-F(L0YP+IXY))/DP
DPZ = (F(L0ZP+IXY+INDB)-F(L0ZP+IXY))/DP
C
DEX = (F(L0XP+IXY+INDI+INDB)-F(L0XP+IXY+INDI))/DE
DEY = (F(L0YP+IXY+INDI+INDB)-F(L0YP+IXY+INDI))/DE
DEZ = (F(L0ZP+IXY+INDI+INDB)-F(L0ZP+IXY+INDI))/DE
C
FENP = F(L0UCT+IXY+INDI)*DPX+F(L0VCT+IXY+INDI)*DPY+
1 F(L0WCT+IXY+INDI)*DPZ
C
GRPHC = (FENP - FP)/(DXC+tiny)
IF(QGE(RUA,0.0)) THEN
FUPW = F(L0UCT+IXY-INDI)*DPX+F(L0VCT+IXY-INDI)*DPY+
1 F(L0WCT+IXY-INDI)*DPZ
GRPHU = (FP - FUPW)/(DXU+tiny)
ELSE
FUPW = F(L0UCT+IXY+2*INDI)*DPX+F(L0VCT+IXY+2*INDI)*DPY+
1 F(L0WCT+IXY+2*INDI)*DPZ
GRPHU = (FUPW - FENP)/(DXU+tiny)
ENDIF
C
FPE = F(L0UCT+IXY)*DEX+F(L0VCT+IXY)*DEY+F(L0WCT+IXY)*DEZ
C
GRPHCI = (FEN - FPE)/(DXC+tiny)
IF(QGE(RUA,0.0)) THEN
FUPW = F(L0UCT+IXY-INDI)*DEX+F(L0VCT+IXY-INDI)*DEY+
1 F(L0WCT+IXY-INDI)*DEZ
GRPHUI = (FPE - FUPW)/(DXU+tiny)
ELSE
FUPW = F(L0UCT+IXY+2*INDI)*DEX+F(L0VCT+IXY+2*INDI)*DEY+
1 F(L0WCT+IXY+2*INDI)*DEZ
GRPHUI = (FUPW - FEN)/(DXU+tiny)
ENDIF
C
ENDIF
C
C.... Use gradients to calculate higher-order correction
IF(ISC==13) THEN
C.... Kappa schemes
FLUXO = RUA*(KAPP(INDVAR)*GRPHC+KAPM(INDVAR)*GRPHU)*GDX
FLUXI = FLUXO
IF(BFC.AND.NONORT.AND.UVW) FLUXI=RUA*
1 (KAPP(INDVAR)*GRPHCI+KAPM(INDVAR)*GRPHUI)*GDX
ELSE
C.... Flux-limited positive schemes
CALL GXFLPS(GRPHC,GRPHU,ISCHEM,PSI)
FLUXO = RUA*PSI*GRPHU*GDX
FLUXI = FLUXO
IF(BFC.AND.NONORT.AND.UVW) THEN
CALL GXFLPS(GRPHCI,GRPHUI,ISCHEM,PSI)
FLUXI = RUA*PSI*GRPHUI*GDX
ENDIF
ENDIF
C
F(L0VAL+IXY) = F(L0VAL+IXY) - FLUXO
F(L0VAL+IXY+INDI) = F(L0VAL+IXY+INDI) + FLUXI
ENDIF
10 CONTINUE
NAMSUB = 'gxhoen'
if(debhcs) call banner(2,namsub,110817)
END
C !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
c
SUBROUTINE GXHOHL(NDIR,ISC,L0DZW,L0DZG,L0AH)
C *********************************************************************
C Purpose: to calculate higher-order correction for HIGH/LOW faces
C on a single slab of cells
C low face high face
C Input: NDIR = 6 5
C Called by: GXHOCS
C *********************************************************************
INCLUDE 'farray'
COMMON
1 /IDATA/ NX,NY,NZ,LUPR1,IDAT1(116)
1 /LDATA/ CARTES,LD1(2),ONEPHS,LD2(3),XCYCLE,LD3(10),STEADY,
1 BFC,LD4(44),NONORT,LD5(19)
1 /IGE/ IXF,IXL,IYF,IYL,IGE1(2),IGR,ISC1,IRUN,IZ,
1 IGE2,ISWEEP,IGE3,INDVAR,IGE4(11)
1 /IZLIM/ IZF,IZL
1 /GENI/ NXNY,IGN1(8),NFM,IGN2(38),NPHI4,IGN3(11)
1 /GHOCS/ L0PHI,L0VAL,L0RUA,L0RHO,L0RHOH,L0R,L0FPR,L0PRP,
1 L0CVL,L0UCT,L0VCT,L0WCT,L0XP,L0YP,L0ZP,LBDXG,
1 LBDYG,LBDZG,KAPP(150),KAPM(150),U1ORU2,V1ORV2,
1 W1ORW2,UVW,STACON,ISCHEM,debhoc,debhcs
1 /NAMFN/ NAMFUN,NAMSUB
1 /RDATA/ TINY,RDAT(84)
C
LOGICAL BLKSLD,DOCOR,U1ORU2,V1ORV2,W1ORW2,CARTES,UVW,LD1,XCYCLE,
1 LD2,STEADY,BFC,LD3,NONORT,LD4,QGE,LD5,ONEPHS,STACON
logical debhoc,debhcs
REAL KAPP,KAPM
CHARACTER*6 NAMFUN,NAMSUB
C
NAMSUB = 'GXHOHL'
C
C.... Set indices for cell geometry
IF(.NOT.BFC) THEN
LDVXY = L0DZW+IZ
LDGXY = L0DZG+IZ
ELSE
LDZG = L0DZG
LDZ = L0DZW
ENDIF
C
C.... Adjust indices by one slab if LOW face
ISLAB=(IZ-1)*NXNY
IF(NDIR==6) THEN
ISLAB=(IZ-2)*NXNY
IF(.NOT.BFC) THEN
LDVXY = LDVXY-1
LDGXY = LDGXY-1
ELSE
LDZG = LDZG-NXNY
LDZ = LDZ-NXNY
L0AH = L0AH-NXNY
ENDIF
ENDIF
C
INDI = NFM
INDZ = 1
IF(BFC) INDZ = NXNY
C
IF(U1ORU2) THEN
IXLP= IXL
IXL = MIN(IXL,(NX-1))
ELSEIF(V1ORV2) THEN
IYLP= IYL
IYL = MIN(IYL,(NY-1))
ENDIF
C.... Cycle over the patch.
DO 10 IX=IXF,IXL
IADD = (IX-1)*NY
DO 10 IY=IYF,IYL
IXY = IY+IADD
C
C.... Check for blocked faces or solid cells within stencil
DOCOR=.NOT.BLKSLD(W1ORW2,U1ORU2,V1ORV2,NXNY,NY,1,IXY+ISLAB,5)
C.... If no blocked/solid cells/faces within stencil then continue
IF(DOCOR) THEN
C
C.... Set mass-flux coefficient for face
RUA = F(L0RUA+IXY)
IF(W1ORW2) THEN
IF(STACON) THEN
RUA = 0.5*(RUA + F(L0RUA+IXY+NXNY))
ELSE
IF(F(L0CVL+IXY)>0.0) THEN
GRO = F(L0RHO+IXY)
IF(.NOT.ONEPHS) GVF = F(L0R+IXY)
ELSE
GRO = F(L0RHOH+IXY)
IF(.NOT.ONEPHS) GVF = F(L0R+IXY+INDI)
ENDIF
GUF = 0.5*(F(L0CVL+IXY) + F(L0CVL+IXY+INDI))
GAF = F(L0AH+IXY)
RUA = GRO*GUF*GAF
IF(.NOT.ONEPHS) RUA=RUA*GVF
ENDIF
ELSEIF(U1ORU2) THEN
RUA = 0.5*(RUA + F(L0RUA+IXY+NY))
ELSEIF(V1ORV2) THEN
RUA = 0.5*(RUA + F(L0RUA+IXY+1))
ENDIF
C
C.... Values of convected variable on each side of face
FP = F(L0PHI+IXY)
FH = F(L0PHI+IXY+INDI)
C
C.... Calculate required cell-geometry data
IF(BFC) THEN
LDGXY = LDZG+IXY
LDVXY = LDZ +IXY
ENDIF
IF(W1ORW2) THEN
DZC = F(LDVXY+INDZ)
IF(QGE(RUA,0.0)) THEN
DZU = F(LDVXY)
GDZ = 0.5*F(LDVXY+INDZ)
ELSE
DZU = F(LDVXY+2*INDZ)
GDZ = -0.5*F(LDVXY+INDZ)
ENDIF
ELSE
DZC = F(LDGXY)
IF(QGE(RUA,0.0)) THEN
DZU = F(LDGXY-INDZ)
GDZ = 0.5*F(LDVXY)
ELSE
DZU = F(LDGXY+INDZ)
GDZ = -0.5*F(LDVXY+INDZ)
ENDIF
ENDIF
C
C.... Calculate gradients of convected variable
IF(.NOT.(BFC.AND.NONORT.AND.UVW)) THEN
C
dzc=dzc+tiny
dzu=dzu+tiny
GRPHC = (FH-FP)/DZC
IF(QGE(RUA,0.0)) THEN
fpnei=F(L0PHI+IXY-INDI)
GRPHU = (FP-F(L0PHI+IXY-INDI))/DZU
ELSE
fpnei= F(L0PHI+IXY+2*INDI)
GRPHU = (F(L0PHI+IXY+2*INDI)-FH)/DZU
ENDIF
C
ELSE
C
IF(W1ORW2) THEN
INDB = NXNY
DP = F(LBDZG+IXY)
ELSEIF(U1ORU2) THEN
INDB = NY
DP = F(LBDXG+IXY)
ELSEIF(V1ORV2) THEN
INDB = 1
DP = F(LBDYG+IXY)
ENDIF
C
dp=dp+tiny
DPX = (F(L0XP+IXY+INDB)-F(L0XP+IXY))/DP
DPY = (F(L0YP+IXY+INDB)-F(L0YP+IXY))/DP
DPZ = (F(L0ZP+IXY+INDB)-F(L0ZP+IXY))/DP
C
IF(NDIR==5) THEN
FH = F(L0UCT+IXY+INDI)*DPX+F(L0VCT+IXY+INDI)*DPY+
1 F(L0WCT+IXY+INDI)*DPZ
ELSE
FP = F(L0UCT+IXY)*DPX+F(L0VCT+IXY)*DPY+F(L0WCT+IXY)*DPZ
ENDIF
C
GRPHC = (FH - FP)/DZC
IF(QGE(RUA,0.0)) THEN
FUPW = F(L0UCT+IXY-INDI)*DPX+F(L0VCT+IXY-INDI)*DPY+
1 F(L0WCT+IXY-INDI)*DPZ
GRPHU = (FP - FUPW)/DZU
ELSE
FUPW = F(L0UCT+IXY+2*INDI)*DPX+F(L0VCT+IXY+2*INDI)*DPY+
1 F(L0WCT+IXY+2*INDI)*DPZ
GRPHU = (FUPW - FH)/DZU
ENDIF
C
ENDIF
C
C.... Use gradients to calculate higher-order correction
IF(ISC==13) THEN
C.... Kappa schemes
FLUX = RUA*(KAPP(INDVAR)*GRPHC+KAPM(INDVAR)*GRPHU)*GDZ
ELSE
C.... Flux-limited positive schemes
CALL GXFLPS(GRPHC,GRPHU,ISCHEM,PSI)
FLUX = RUA*PSI*GRPHU*GDZ
ENDIF
C
IF(NDIR==5) THEN
F(L0VAL+IXY) = F(L0VAL+IXY) - FLUX
ELSE
F(L0VAL+IXY) = F(L0VAL+IXY) + FLUX
ENDIF
ENDIF
C
10 CONTINUE
C
IF(U1ORU2) THEN
IXL = IXLP
ELSEIF(V1ORV2) THEN
IYL = IYLP
ENDIF
C
NAMSUB = 'gxhohl'
C
END
C !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
c
SUBROUTINE GXFLPS(GRC,GRU,ISC,PSI)
C *********************************************************************
C Purpose: to calculate flux-limiter functions for Flux-Limited
C Positive Schemes. Ten limiters have been implemented:
C MUSCL, van Leer harmonic, van Albada, Koren, SMART,
C Minmod, OSPRE, H-Quick, Superbee and UMIST. Others may
C be implemented by imitation.
C
C Input: GRC - gradient of convected variable across face
C GRU - gradient of convected variable upwind of face
C ISC - scheme number which indicates scheme selection
C
C Output: PSI - Flux-limiter function
C Called by: GXHOEN, GXHOHL
C *********************************************************************
C
c.... initialisation in case of inappropriate entry
PSI=0.0
RP=(GRC+1.E-10)/(GRU+1.E-10)
C
IF(ISC==6) THEN
C
C..SMART: PLNS limiter based on QUICK (Gaskell & Lau [1988])
C
R1=AMIN1(0.25+0.75*RP,4.0)
R1=AMIN1(R1,2.0*RP)
PSI=AMAX1(0.0,R1)
C
ELSEIF(ISC==7) THEN
C
C..Koren: PLNS limiter based on CUS (Koren [1993])
C
R1=AMIN1(0.33333+0.66666*RP,2.0)
R1=AMIN1(R1,2.0*RP)
PSI=AMAX1(1.E-20,R1)
C
ELSEIF(ISC==8) THEN
C
C..van Leer1/MUSCL : PLS limiter based on Fromm & identical to Noll'S
C MLU scheme (van Leer[1979])
C
R1=AMIN1(0.5+0.5*RP,2.0)
R1=AMIN1(R1,2.0*RP)
PSI=AMAX1(1.E-20,R1)
C
ELSEIF(ISC==9) THEN
C
C..H-QUICK: HNS limiter based on QUICK (Deconinck & Waterson [1995])
C
IF(RP>0.0) THEN
PSI=4.0*RP/(RP+3.0)
ELSE
PSI=1.0E-20
ENDIF
C
ELSEIF(ISC==10) THEN
C
C..OSPRE: PRS limiter (Deconinck & Waterson [1995])
C
RP2=RP*RP
PSI=1.5*(RP2+RP)/(RP2+RP+1.0)
C
ELSEIF(ISC==11) THEN
C
C..van Leer2: PRS harmonic limiter based on Fromm, which is
C identical to Zhu HLPA scheme (see Hirsch[1990])
C
IF(RP>0.0) THEN
PSI=2.0*RP/(RP+1.0)
ELSE
PSI=1.0E-20
ENDIF
C
ELSEIF(ISC==12) THEN
C
C..van Albada: 'classical' limiter (van Albada et al [1982])
C
PSI=RP*(RP+1.0)/(RP*RP+1.0)
C
ELSEIF(ISC==13) THEN
C
C..Minmod: 'classical' limiter, which is identical to Zhu/Rodi SOUCUP
C scheme (see Roe [1986])
C
RP=AMIN1(RP,1.0)
PSI=AMAX1(0.0,RP)
C
ELSEIF(ISC==14) THEN
C
C..Superbee: 'classical' limiter (see Roe [1986])
C
R1=AMIN1(2*RP,1.0)
R2=AMIN1(RP,2.0)
R2=AMAX1(R1,R2)
PSI=AMAX1(0.0,R2)
C
ELSEIF(ISC==15) THEN
C
C..UMIST: PLS limiter based mainly on QUICK Lien & Leschziner [1994]
C
R1=AMIN1(0.75+0.25*RP,2.0)
R2=AMIN1(0.25+0.75*RP,2.0*RP)
R1=AMIN1(R1,R2)
PSI=AMAX1(0.0,R1)
C
ELSEIF(ISC==16) THEN
C
C..H-CUS: HNS limiter based on CUS (Deconinck & Waterson [1995])
C
IF(RP>0.0) THEN
PSI=3.0*RP/(RP+2.0)
ELSE
PSI=1.0E-20
ENDIF
C
ELSEIF(ISC==17) THEN
C
C..CHARM: PRNS limiter based on QUICK (Zhou [1995])
C
IF(RP>0.0) THEN
PSI=RP*(3.*RP+1.)/(RP*RP+2.0*RP+1.0)
ELSE
PSI=1.0E-20
ENDIF
ENDIF
C
END
C !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
FUNCTION BLKSLD(VELI,VELN1,VELN2,INDI,INDN1,INDN2,IJK,IDIR)
C *********************************************************************
C Purpose: to detect presence of blocked faces or solid cells
C within stencil used to calculate higher-order correction
C for a single cell face. If BLKSLD is .TRUE. then no
C higher-order correction will be calculated.
C
C Input: VELI - .TRUE. if variable is "in-line" velocity
C VELN1 - .TRUE. if variable is NOT "in-line" velocity
C VELN2 - .TRUE. if variable is NOT "in-line" velocity
C INDI - Offset index in dirn. normal to face
C INDN1 - Offset index corresponding to VELN1
C INDN2 - Offset index corresponding to VELN2
C IJK - IY+(IX-1)*NY + (IZ-1)*NXNY
C IDIR -
C
C Output: BLKSLD = .TRUE. if blockage/solid detected
C Called by: GXHOEN, GXHOHL
C *********************************************************************
C
INCLUDE 'farray'
C
LOGICAL BLKSLD,VELI,VELN1,VELN2,LSLDIR,LSOLID
C
BLKSLD = LSOLID(IJK)
IF(BLKSLD) RETURN
C.... Check for blocked faces
BLKSLD = LSLDIR(IJK,IDIR)
BLKSLD = BLKSLD.OR.LSLDIR(IJK+INDI,IDIR)
BLKSLD = BLKSLD.OR.LSLDIR(IJK-INDI,IDIR)
IF(BLKSLD) RETURN
C
IF(VELI) THEN
BLKSLD = LSLDIR(IJK+2*INDI,IDIR)
ELSEIF(VELN1) THEN
BLKSLD = LSLDIR(IJK+INDN1,IDIR)
BLKSLD = BLKSLD.OR.LSLDIR(IJK+INDI+INDN1,IDIR)
BLKSLD = BLKSLD.OR.LSLDIR(IJK-INDI+INDN1,IDIR)
ELSEIF(VELN2) THEN
BLKSLD = LSLDIR(IJK+INDN2,IDIR)
BLKSLD = BLKSLD.OR.LSLDIR(IJK+INDI+INDN2,IDIR)
BLKSLD = BLKSLD.OR.LSLDIR(IJK-INDI+INDN2,IDIR)
ENDIF
C
END
c