c
C.... file name GXMISCSO.F 240924
c-->
C.... file name GXMISCSO.F 261109
C**** SUBROUTINE GXPOLR is called from group 13 of GREX3, by setting
C the value ascribed to GROUND in the COVAL statement, and is
C entered only when the patch name with the 2nd to 4th
C characters of 'POL'.
C
C.... The dummy NP is the first two characters of the patch name
C used in the SATELLITE; UP should be used for x-direction momentum
C equations, and VP for the y-direction momentum equations.
C
C.... The library cases 222-226,237 make use of it.
C
SUBROUTINE GXPOLR(NP)
INCLUDE 'farray'
INCLUDE 'grdloc'
INCLUDE 'satgrd'
COMMON/IGE/IXF,IXL,IYF,IYL,IREG,NZSTEP,IGR,ISC,IRUN,IZSTEP,ITHYD,
1 ISWEEP,ISTEP,INDVAR,VAL,CO,NDIREC,WALDIS,PATGEO,IGES20(6)
INTEGER VAL,CO,WALDIS,PATGEO
COMMON/NAMFN/NAMFUN,NAMSUB
CHARACTER*6 NAMFUN,NAMSUB
C
c fn25(y,a) y = a*y
c fn41(y,x,a,b) y = sin(a*x+b)
c fn42(y,x,a,b) y = cos(a*x+b)
c POLRA is the flow speed.
c
NAMSUB = 'GXPOLR'
c------------------------------ val = grnd1 or setspeed
IF(ISC==13) THEN
IF(NP=='UP'.AND.(INDVAR==U1.OR.INDVAR==U2)) THEN
CALL FN41(VAL,XU2D,1.0,0.0)
CALL FN25(VAL,-POLRA)
ELSE
IF(NP=='VP'.AND.(INDVAR==V1.OR.INDVAR==V2)) THEN
CALL FN42(VAL,XG2D,1.0,0.0)
CALL FN25(VAL,POLRA)
ENDIF
ENDIF
ENDIF
NAMSUB = 'gxpolr'
END
C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
C.... GXPDRP is called from group 13 of EARTH, by setting the coefficient
C to GRND-value in the SPEDAT command set for a porous 'plate' or
C 'thin-plate' object:
C SPEDAT(SET,PDROP_LAW,NamPat,R,GRND*),
C where NamPat is the name of the object. This ascribes a pressure
C drop formula, determined by the value of GRND*. as follows:
C GRND1 - Dp = Const * U**Power
C GRND2 - Dp = Const * 0.5 * Dens * U**2,
C here U is the device or superficial velocity component across the plate.
C The choice between superficial and device is made by a SPEDAT command:
C SPEDAT(SET,PDROP_VEL,NamPat,R,value)
C where value = 0 for device velocity or = 1 for superficial velocity.
C The coefficient for GRND1 and GRND2 is set by another SPEDAT:
C SPEDAT(SET,PDROP_COE,NamPat,R,value)
C The power for GRND1 is set by the SPEDAT:
C SPEDAT(SET,PDROP_POW,NamPat,R,value)
C Note, that this command will have an effect only if the porosity
C of a 'thin-plate' object is set to a non-zero value by the command
C SPEDAT(SET,POROSITY,NamPat,R,Value),
C where 0.< Value <1. specifies the plate active area.
C
C A 'thin-plate' allows heat transfer through the plate. The nominal
C thickness and material number are set by:
C COVAL(NamPat,PRPS, Material, Thickness)
C
C A 'plate' does not allow heat transfer, but does allow different
C heat sources on either side.
C
C NOTE: If this routine is to be used in a PIL-based Q1, the following
C rules should be observed:
C
C A THIN-PLATE is defined by a PATCH with name starting PLT*.
C NamPat in the SPEDATs above must be the same as the patch name.
C
C A PLATE is defined by a PATCH with name starting PPD*, e.g. PPD*abcd
C NamPat in the SPEDATs above must start with PLT*, e.g. PLT*abcd.
SUBROUTINE GXPDRP
INCLUDE 'farray'
INCLUDE 'satear'
INCLUDE 'grdloc'
INCLUDE 'satgrd'
INCLUDE 'grdear'
COMMON /UVWCOL/IUC1,IVC1,IWC1,IUVW1(3),IUC2,IVC2,IWC2,IUVW2(23)
COMMON /UVWGBF/ IUC1GCV,IVC1GCV,IWC1GCV,IFILGCV(9)
COMMON/NAMFN/NAMFUN,NAMSUB
LOGICAL FLUID1,MASKPT
CHARACTER*6 NAMFUN,NAMSUB
C
NAMSUB= 'GXPDRP'
IF(ISC==2 .OR. ISC==3) THEN
L0CO = L0F(CO)
L0VEL= L0F(INDVAR)
CONST= GETPCN(0,IPAT,MASKPT(IPAT))
IF(ISC==2) THEN
C.... GRND1 coefficient gives pressure drop proportional to the power of
C the superficial velocity across the plate:
POWER= GETPCN(1,IPAT,MASKPT(IPAT)) - 1.
DO IX= IXF,IXL
IAD= (IX-1)*NY
DO IY= IYF,IYL
I= IY + IAD
VELPLT= F(L0VEL+I)+TINY
F(L0CO+I)= CONST*ABS(VELPLT)**POWER
ENDDO
ENDDO
ELSE
C.... GRND2 coefficient gives pressure drop proportional to the dynamic
C pressure across the plate:
LRHO12= ITWO(LRHO1,LRHO2,FLUID1(INDVAR))
L0RHO = L0F(LRHO12)
IF(INDVAR==U1.OR.INDVAR==U2.OR.INDVAR==IUC1GCV.OR.
1 INDVAR==IUC1.OR.INDVAR==IUC2) THEN
LRHON=EAST(LRHO12)
ELSEIF(INDVAR==V1.OR.INDVAR==V2.OR.INDVAR==IVC1GCV.OR.
2 INDVAR==IVC1.OR.INDVAR==IVC2) THEN
LRHON=NORTH(LRHO12)
ELSEIF(INDVAR==W1.OR.INDVAR==W2.OR.INDVAR==IWC1GCV.OR.
2 INDVAR==IWC1.OR.INDVAR==IWC2) THEN
LRHON=ITWO(LRHO1H,LRHO2H,FLUID1(INDVAR))
ENDIF
L0RHON=L0F(LRHON)
DO IX= IXF,IXL
IAD= (IX-1)*NY
DO IY= IYF,IYL
I= IY + IAD
IF(F(L0VEL+I)>0.0) THEN
DENS=F(L0RHO+I)
ELSE
DENS=F(L0RHON+I)
ENDIF
F(L0CO+I)= 0.5*CONST*DENS*(ABS(F(L0VEL+I))+TINY)
ENDDO
ENDDO
ENDIF
ENDIF
NAMSUB= 'gxpdrp'
END
C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
C.... GXDENDIF is called from group 13 of EARTH, for patch names beginning
C DENDIF. It sets VAL to for velocities across faces having densities
C on each side which differ by than 1.0
C
SUBROUTINE GXDENDIF
INCLUDE 'farray'
INCLUDE 'satear'
INCLUDE 'grdloc'
INCLUDE 'satgrd'
INCLUDE 'grdear'
COMMON/NAMFN/NAMFUN,NAMSUB
LOGICAL FLUID1
CHARACTER*6 NAMFUN,NAMSUB
C
NAMSUB= 'DENDIF'
L0CO = L0F(CO)
L0VAL = L0F(VAL)
LRHO12= ITWO(LRHO1,LRHO2,FLUID1(INDVAR))
L0RHO = L0F(LRHO12)
IF(INDVAR==U1.OR.INDVAR==U2) THEN
LRHON=EAST(LRHO12)
ELSEIF(INDVAR==V1.OR.INDVAR==V2) THEN
LRHON=NORTH(LRHO12)
ELSEIF(INDVAR==W1.OR.INDVAR==W2) THEN
LRHON=ITWO(LRHO1H,LRHO2H,FLUID1(INDVAR))
ENDIF
L0RHON=L0F(LRHON)
DO 20 IX= IXF,IXL
IAD= (IX-1)*NY
DO 20 IY= IYF,IYL
I= IY + IAD
DIFF=ABS(F(L0RHO+I) - F(L0RHON+I))
IF(DIFF>1.0) THEN
F(L0VAL+I)= 0.0
ELSE
F(L0CO+I) = 0.0
ENDIF
20 CONTINUE
NAMSUB= 'dendif'
END
C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
C.... GETPCN retrieves value of either coefficient (NGO=0), or power
C (NGO=1) specified for a porous 'thin-plate' object. GETPCN is
C called from GXPDRP.
FUNCTION GETPCN(NGO,IPAT,VRPAT)
INCLUDE 'patcmn'
LOGICAL VRPAT,LTMP,FIRST
CHARACTER NPATCH*8, MODEL*10, CTMP
C.... Preliminaries. Conver the name of a pressure drop patch into
C the name of the correponding 'thin-plate' patch
IF(VRPAT) THEN
NPATCH= '^PLT*'//NAMPAT(IPAT)(5:7)
ELSE
NPATCH= 'PLT*'//NAMPAT(IPAT)(5:8)
ENDIF
GETPCN= 0.0
FIRST = .TRUE.
IF(NGO==0) THEN
MODEL= 'PDROP_COE'
ELSE
MODEL= 'PDROP_PWR'
ENDIF
10 CALL GETSPD(MODEL,NPATCH,1,RTMP,ITMP,LTMP,CTMP,IERR)
IF(IERR==0) THEN
GETPCN= RTMP
ELSEIF(FIRST) THEN
FIRST= .FALSE.
IF(NPATCH(4:4)=='*') THEN
NPATCH(4:4)= '_'
ELSE
NPATCH(4:4)= '*'
ENDIF
GO TO 10
ENDIF
END
C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
C... GXOUTLET deduces the inflow velocity at a fixed pressure boundary
C from the mass inflow divided by the cell density and area. Allowance
C is made to relax the inflow velocity.
C The PATCH commands are:
C COVAL(patch_name, P1, pco, pval) - standard fixed pressure setting
C COVAL(patch_name, vel, onlyms, GRND1) - vel is U1 through W2
C The relaxation is set via SPEDAT as follows:
C SPEDAT(SET,object_name,RELAX,R,relax) - relaxation factor 0MAXDMN) THEN
CALL WRITBL
CALL WRITST
CALL WRIT40('Please increase MAXDMN in GXOUTLET')
CALL WRIT2I('Current ',MAXDMN,'; Needed',NUMDMN)
CALL WRITST
CALL SET_ERR(557,'MAXDMN too small in GXINOUT',1)
RETURN
ENDIF
100 CONTINUE
IF(IDMN>1) CALL INDXDM
NOUT(IDMN)=0
NCELL=0
DO IPAT=1,NUMPAT ! loop over patches counting outlets
IF(.NOT.LPTDMN(IPAT)) CYCLE ! not for this domain
IF(IS_OUT(IPAT)) THEN ! count and get no of cells covered
NOUT(IDMN)=NOUT(IDMN)+1
CALL GETPAT(IPAT,IR,GTYP,IX1,IX2,IY1,IY2,IZ1,IZ2,IT1,IT2)
NCELL=MAX(NCELL,(IX2-IX1+1)*(IY2-IY1+1)*(IZ2-IZ1+1))
ENDIF
ENDDO
C... allocate storage
CALL GXMAKE0(L0REL(IDMN),NOUT(IDMN),'RELX') ! relaxation factor
CALL GXMAKE0(L0RAT(IDMN),NOUT(IDMN),'ARAT') ! area ratio
CALL GXMAKE0(L0VEL(IDMN),NOUT(IDMN)*NCELL,'VELIN') ! initial guessed velocity
CALL GXMAKE0(L0OUT(IDMN),NUMPAT,'IOUT') ! sequence number
IF(.NOT.ONEPHS) THEN
CALL GXMAKE0(L0RL2(IDMN),NOUT(IDMN),'RELX2')
CALL GXMAKE0(L0VL2(IDMN),NOUT(IDMN)*NCELL,'VELIN2')
ENDIF
IOUT=0
DO IPAT=1,NUMPAT ! loop again saving settings from Q1
IF(.NOT.LPTDMN(IPAT)) CYCLE
IF(IS_OUT(IPAT)) THEN
COBNAM=OBJNAM(IPAT)
IF(COBNAM.EQ.'NOTSET') COBNAM=NAMPAT(IPAT) ! use patch name if not object
IOUT=IOUT+1
F(L0OUT(IDMN)+IPAT)=IOUT ! save sequence number
VELIN=-999.9
CALL GETSDR(COBNAM,'VELIN',VELIN)
IF(QNE(VELIN,-999.9)) THEN ! set whole patch velocity to initial guess
DO II=1,NCELL
F(L0VEL(IDMN)+(IOUT-1)*NCELL+II)=VELIN
ENDDO
ENDIF
RELX=0.3
CALL GETSDR(COBNAM,'RELAX',RELX) ! relaxation factor
F(L0REL(IDMN)+IOUT)=RELX
IF(.NOT.ONEPHS) THEN
VELIN=-999.9
CALL GETSDR(COBNAM,'VELIN2',VELIN)
IF(QNE(VELIN,-999.9)) THEN
DO II=1,NCELL
F(L0VL2(IDMN)+(IOUT-1)*NCELL+II)=VELIN
ENDDO
ENDIF
RELX=0.3
CALL GETSDR(COBNAM,'RELAX2',RELX)
F(L0RL2(IDMN)+IOUT)=RELX
ENDIF
IF(MASKPT(IPAT)) THEN
CTEMP='^'//NAMPAT(IPAT)
ELSE
CTEMP='!'//NAMPAT(IPAT)
ENDIF
ARAT=1.0
CALL GETSDR('ARATIO',CTEMP,ARAT) ! area ratio
ARAT=AMAX1(ARAT,0.0)
F(L0RAT(IDMN)+IOUT)=ARAT
ENDIF
ENDDO
C... loop back for next FGV domain
IF(IDMN1) THEN
IDMN=1
CALL INDXDM
ENDIF
C*****************************************************************
C
C--- GROUP 13. Boundary conditions and special sources
C Index for Coefficient - CO
C Index for Value - VAL
ELSEIF(IGR==13.AND.ISC==13) THEN
C------------------- SECTION 14 ------------------- value = GRND1
C For COVAL(patch, velocity, onlyms,GRND1) deduce inflow velocity
C from mass source
IOUT=NINT(F(L0OUT(IDMN)+IPAT)) ! sequence number of outlet
IF(IOUT==0) RETURN ! nothing stored
C... check patch type
CALL GETPAT(IPAT,IREG,RTYP,JXF,JXL,JYF,JYL,JZF,JZL,JTF,JTL)
ITYP=RTYP
C... set area index and flow direction indicator MULT
C MULT = +1 for U at West, V at South, W at Low
C = -1 for U at East, V at North , W at High
C = 0 for all other combinations
IF(ITYP==2) THEN ! East
KGEOM=KXYAE
MULT=ITWO(-1,0,INDVAR==U1.OR.INDVAR==U2.OR.INDVAR==IUC1GCV)
ELSEIF(ITYP==3) THEN ! West
KGEOM=KXYAW
IF(STORGEO.AND.JXF==1) CALL DOM_BOUND
MULT=ITWO( 1,0,INDVAR==U1.OR.INDVAR==U2.OR.INDVAR==IUC1GCV)
ELSEIF(ITYP==4) THEN ! North
KGEOM=KXYAN
MULT=ITWO(-1,0,INDVAR==V1.OR.INDVAR==V2.OR.INDVAR==IVC1GCV)
ELSEIF(ITYP==5) THEN ! South
KGEOM=KXYAS
IF(STORGEO.AND.JYF==1) CALL DOM_BOUND
MULT=ITWO( 1,0,INDVAR==V1.OR.INDVAR==V2.OR.INDVAR==IVC1GCV)
ELSEIF(ITYP==6) THEN ! High
KGEOM=KXYAH
MULT=ITWO(-1,0,INDVAR==W1.OR.INDVAR==W2.OR.INDVAR==IWC1GCV)
ELSE ! Low
KGEOM=KXYAL
IF(STORGEO.AND.JZF==1) CALL DOM_BOUND
MULT=ITWO( 1,0,INDVAR==W1.OR.INDVAR==W2.OR.INDVAR==IWC1GCV)
ENDIF
IF(MULT/=0) THEN ! something to do, velocity normal to face
C... use patch-wise store for mass source, as more reliable
IF(FLUID1(INDVAR)) THEN
KPVMAS=PVMASS ! mass source
L0DEN=L0F(DEN1) ! density
RELX=F(L0REL(IDMN)+IOUT) ! velocity relaxation
L0V=L0VEL(IDMN)+(IOUT-1)*NCELL ! previous sweeps velocity
LBVOUT=LBNAME('VOUT') ! optional storage for inflow velocity
ELSE
KPVMAS=PVMAS2
L0DEN=L0F(DEN2)
RELX=F(L0RL2(IDMN)+IOUT)
L0V=L0VL2(IDMN)+(IOUT-1)*NCELL
LBVOUT=LBNAME('VOU2') ! optional storage for inflow velocity
ENDIF
L0MIN = L0PVAR(KPVMAS,IPAT,IZ)
IF(LBVOUT>0) L0VOUT=L0F(LBVOUT)
C... get area ratio
ARAT=F(L0RAT(IDMN)+IOUT)
C... get index for VAL
L0VAL=L0F(VAL)
RMULT=FLOAT(MULT)
IZADD=(IZ-JZF)*(JXL-JXF+1)*(JYL-JYF+1)
C... High mass sources for W1 are always at IZ+1
IF(LWPZP1) THEN
L0MIN = L0PVAR(KPVMAS,IPAT,IZ+1)
IZADD=(IZ+1-JZF)*(JXL-JXF+1)*(JYL-JYF+1)
IF(LBVOUT>0) L0VOUT=L0F(ANYZ(LBVOUT,IZ+1))
ENDIF
IADD=ITWO(NX*NY,0,INDVAR>6.AND.JZF0) F(L0VOUT+I)=VEL ! store for print/plot
ENDIF
C... set boundary value
F(L0VAL+I)=VEL
ELSE
F(L0VAL+I)=0.0
ENDIF
ENDDO
ENDDO
ELSE
C... nothing to do - velocity is not normal to face
CALL FN1(VAL,0.0)
ENDIF
ENDIF
END
C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
LOGICAL FUNCTION IS_OUT(IPAT)
INCLUDE 'patcmn'
INCLUDE 'objnam'
COMMON /RDATA/ RD1(25),GRND,RD4,FIXFLU,RD2(32),SAME,RD3(24)
LOGICAL MASKPT,QNE
CHARACTER*14 COBTYP, CTEMP
C... check if object type is outlet
IF(OBJNAM(IPAT)=='NOTSET') THEN
CALL GETCV(IPAT,9,GCO1,GVAL2)
CALL GETCV(IPAT,10,GCO2,GVAL2)
IS_OUT=(GCO1>0.0.AND.QNE(GCO1,FIXFLU)) .OR. (GCO2>0.AND.
1 QNE(GCO2,FIXFLU))
IS_OUT=IS_OUT.OR.(GCO1/=-999.0.AND.GCO1<0.0.AND.GCO1>GRND).OR.
1 (GCO2/=-999.0.AND.GCO2<0.0.AND.GCO2>GRND)
ELSE
IF(MASKPT(IPAT)) THEN
CTEMP='^'//NAMPAT(IPAT)
ELSE
CTEMP='!'//NAMPAT(IPAT)
ENDIF
COBTYP=' '
CALL GETSDC('OBJTYP',CTEMP,COBTYP)
IS_OUT=COBTYP=='OUTLET'.OR.COBTYP=='OPENING'.OR.
1 COBTYP=='APERTURE'
ENDIF
END