Skip to content

Commit a756de1

Browse files
authored
Merge pull request #14739 from ericvmueller/master
FDS Source: update Z_LS calculation to properly account for terrain c…
2 parents 2349cf6 + 709573d commit a756de1

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

Source/vege.f90

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ MODULE VEGE
1818
TYPE(MESH_TYPE), POINTER :: M
1919
TYPE(WALL_TYPE), POINTER :: WC
2020
TYPE(CFACE_TYPE), POINTER :: CFA
21+
TYPE(CC_CUTFACE_TYPE), POINTER :: CF
2122
TYPE(SURFACE_TYPE), POINTER :: SF
2223
TYPE(BOUNDARY_PROP1_TYPE), POINTER :: B1
2324
TYPE(BOUNDARY_PROP2_TYPE), POINTER :: B2
@@ -37,7 +38,7 @@ SUBROUTINE INITIALIZE_LEVEL_SET_FIRESPREAD_1(NM)
3738
USE COMPLEX_GEOMETRY, ONLY : CC_IDCF
3839
INTEGER, INTENT(IN) :: NM
3940
INTEGER :: ICF,IW,I,J,SURF_INDEX
40-
REAL(EB), ALLOCATABLE, DIMENSION(:,:) :: SUM_AREA
41+
REAL(EB), ALLOCATABLE, DIMENSION(:,:) :: MAX_AREA,SUM_AREA
4142

4243
T_NOW = CURRENT_TIME()
4344

@@ -78,38 +79,43 @@ SUBROUTINE INITIALIZE_LEVEL_SET_FIRESPREAD_1(NM)
7879

7980
IF (CC_IBM) THEN
8081

82+
ALLOCATE(MAX_AREA(0:IBP1,0:JBP1)) ; MAX_AREA = 0._EB
8183
ALLOCATE(SUM_AREA(0:IBP1,0:JBP1)) ; SUM_AREA = 0._EB
8284
ALLOCATE(M%LS_KLO_TERRAIN(0:IBP1,0:JBP1),STAT=IZERO) ; CALL ChkMemErr('READ','LS_KLO_TERRAIN',IZERO)
8385
LS_KLO_TERRAIN => M%LS_KLO_TERRAIN ; LS_KLO_TERRAIN = 2*KBP1+1 ! Number larger that KBP1.
8486
ALLOCATE(M%LS_KHI_TERRAIN(0:IBP1,0:JBP1),STAT=IZERO) ; CALL ChkMemErr('READ','LS_KHI_TERRAIN',IZERO)
8587
LS_KHI_TERRAIN => M%LS_KHI_TERRAIN ; LS_KHI_TERRAIN = -1 ! Number smaller than 0.
8688
DO ICF=1,M%N_CUTFACE_MESH
87-
IF (CUT_FACE(ICF)%STATUS/=2 .OR. CUT_FACE(ICF)%NFACE<1) CYCLE ! CC_INBOUNDARY == 2
89+
CF => CUT_FACE(ICF)
90+
IF (CF%STATUS/=2 .OR. CF%NFACE<1) CYCLE ! CC_INBOUNDARY == 2
8891
! Location of CFACE with largest AREA, to define SURF_INDEX:
89-
IW = MAXLOC(CUT_FACE(ICF)%AREA(1:CUT_FACE(ICF)%NFACE),DIM=1)
90-
CFA => CFACE( CUT_FACE(ICF)%CFACE_INDEX(IW) )
91-
BC => BOUNDARY_COORD(CFA%BC_INDEX)
92-
IF (BC%KKG < LS_KLO_TERRAIN(BC%IIG,BC%JJG)) LS_KLO_TERRAIN(BC%IIG,BC%JJG) = BC%KKG
93-
IF (BC%KKG > LS_KHI_TERRAIN(BC%IIG,BC%JJG)) LS_KHI_TERRAIN(BC%IIG,BC%JJG) = BC%KKG
92+
IW = MAXLOC(CF%AREA(1:CF%NFACE),DIM=1)
93+
CFA => CFACE(CF%CFACE_INDEX(IW) )
94+
BC => BOUNDARY_COORD(CFA%BC_INDEX)
9495
IF (BC%NVEC(KAXIS)>-TWO_EPSILON_EB .AND. CFA%BOUNDARY_TYPE==SOLID_BOUNDARY) THEN
95-
IF (SUM(CUT_FACE(ICF)%AREA(1:CUT_FACE(ICF)%NFACE))<SUM_AREA(BC%IIG,BC%JJG)) THEN
96+
IF (BC%KKG < LS_KLO_TERRAIN(BC%IIG,BC%JJG)) LS_KLO_TERRAIN(BC%IIG,BC%JJG) = BC%KKG
97+
IF (BC%KKG > LS_KHI_TERRAIN(BC%IIG,BC%JJG)) LS_KHI_TERRAIN(BC%IIG,BC%JJG) = BC%KKG
98+
SUM_AREA(BC%IIG,BC%JJG) = SUM_AREA(BC%IIG,BC%JJG) + SUM(CF%AREA(1:CF%NFACE))
99+
Z_LS(BC%IIG,BC%JJG) = Z_LS(BC%IIG,BC%JJG) + DOT_PRODUCT(CF%XYZCEN(KAXIS,1:CF%NFACE),CF%AREA(1:CF%NFACE))
100+
IF (SUM(CF%AREA(1:CF%NFACE))<MAX_AREA(BC%IIG,BC%JJG)) THEN
96101
CYCLE ! This CUT_FACE does not contain the majority of the area corresponding to the FDS cell area, DX*DY
97102
ELSE
98-
SUM_AREA(BC%IIG,BC%JJG) = SUM(CUT_FACE(ICF)%AREA(1:CUT_FACE(ICF)%NFACE))
103+
MAX_AREA(BC%IIG,BC%JJG) = SUM(CF%AREA(1:CF%NFACE))
99104
ENDIF
100-
! Area averaged Z height of CFACES within this cut-cell (containing CC_INBOUNDARY CFACES):
101-
Z_LS(BC%IIG,BC%JJG) = DOT_PRODUCT(CUT_FACE(ICF)%XYZCEN(KAXIS,1:CUT_FACE(ICF)%NFACE), &
102-
CUT_FACE(ICF)%AREA(1:CUT_FACE(ICF)%NFACE) ) / SUM_AREA(BC%IIG,BC%JJG)
103105
IF (BC%KKG > K_LS(BC%IIG,BC%JJG)) K_LS(BC%IIG,BC%JJG) = BC%KKG
104106
LS_SURF_INDEX(BC%IIG,BC%JJG) = CFA%SURF_INDEX
105107
ENDIF
106108
ENDDO
109+
WHERE (SUM_AREA>TWO_EPSILON_EB) Z_LS = Z_LS/SUM_AREA
110+
DEALLOCATE(MAX_AREA)
111+
DEALLOCATE(SUM_AREA)
112+
107113
DO J=1,JBAR
108114
DO I=1,IBAR
109115
IF (K_LS(I,J)==KBAR .AND. FCVAR(I,J,K_LS(I,J),CC_IDCF,KAXIS)>0) LS_SURF_INDEX(I,J) = 0
110116
ENDDO
111117
ENDDO
112-
DEALLOCATE(SUM_AREA)
118+
113119
ENDIF
114120

115121
! Set up level set on cartesian faces only where they are not under a GEOM
@@ -155,7 +161,7 @@ END SUBROUTINE INITIALIZE_LEVEL_SET_FIRESPREAD_1
155161
SUBROUTINE INITIALIZE_LEVEL_SET_FIRESPREAD_2(NM,MODE)
156162

157163
INTEGER, INTENT(IN) :: NM,MODE
158-
INTEGER :: I,IM1,IM2,IIG,IP1,IP2,J,JJG,JM1,JP1
164+
INTEGER :: I,IM1,IIG,IP1,J,JJG,JM1,JP1
159165
REAL(EB) :: DZT_DUM,DZTDX_DUM,DZTDY_DUM,G_EAST,G_WEST,G_SOUTH,G_NORTH
160166

161167
T_NOW = CURRENT_TIME()
@@ -236,17 +242,13 @@ SUBROUTINE INITIALIZE_LEVEL_SET_FIRESPREAD_2(NM,MODE)
236242

237243
GRADIENT_ILOOP: DO I = 1,IBAR
238244

239-
IM1=I-1 ; IM2=I-2
240-
IP1=I+1 ; IP2=I+2
241-
IF (I==1) IM1 = I
242-
IF (I==IBAR) IP1 = I
245+
IM1=I-1
246+
IP1=I+1
243247

244248
DO J = 1,JBAR
245249

246250
JM1=J-1
247251
JP1=J+1
248-
IF (J==1) JM1 = J
249-
IF (J==IBAR) JP1 = J
250252

251253
G_EAST = 0.5_EB*( Z_LS(I,J) + Z_LS(IP1,J) )
252254
G_WEST = 0.5_EB*( Z_LS(I,J) + Z_LS(IM1,J) )
@@ -489,7 +491,6 @@ SUBROUTINE LEVEL_SET_FIRESPREAD(T,DT,NM)
489491
! and then calculating effective wind speed, phi_s is converted to an effected wind speed and added
490492
! to UMF calculated from the wind. Effective U has units of m/min in Wilson formula.
491493
! 0.3048 ~= 1/3.281
492-
! if phi_s < 0 then a complex value (NaN) results. Using abs(phi_s) and sign function to correct.
493494

494495
UMF_TMP = &
495496
0.3048_EB/PHI_S*(((SF%VEG_LSET_BETA / BETA_OP_ROTH)**E_ROTH)*PHI_S/C_ROTH)**(1._EB/B_ROTH)

0 commit comments

Comments
 (0)