📄 init.f90
字号:
ENDIFIF (I_OBST>0 .AND. SURFACE(IBCX)%MASS_FLUX_TOTAL/=-999._EB) THEN OBX=>M%OBSTRUCTION(I_OBST) M%UW0(IW) = SURFACE(IBCX)%MASS_FLUX_TOTAL / RHOA * M%AREA_ADJUST(IW)ENDIF T_ACTIVATE = -1._EBVENT_FOUND = .FALSE. ! Check if there is a vent embedded in the surface VLOOP: DO N=1,M%N_VENT VT => M%VENTS(N) IF (I_OBST>0) THEN IF (VT%BOUNDARY_TYPE==OPEN_BOUNDARY) CYCLE VLOOP IF (.NOT.M%OBSTRUCTION(I_OBST)%ALLOW_VENT) CYCLE VLOOP ENDIF IF (VT%IOR/=IOR) CYCLE VLOOP IF (IBCX==INTERPOLATED_SURF_INDEX) CYCLE VLOOP IF ((VT%BOUNDARY_TYPE==OPEN_BOUNDARY .OR. VT%BOUNDARY_TYPE==MIRROR_BOUNDARY) .AND.M%IJKW(9,IW)>0) CYCLE VLOOP IF (ABS(IOR)==1) THEN IF (IOR== 1 .AND. I/=VT%I1 ) CYCLE VLOOP IF (IOR==-1 .AND. I/=VT%I1+1) CYCLE VLOOP IF (J<VT%J1+1 .OR. J>VT%J2) CYCLE VLOOP IF (K<VT%K1+1 .OR. K>VT%K2) CYCLE VLOOP ENDIF IF (ABS(IOR)==2) THEN IF (IOR== 2 .AND. J/=VT%J1 ) CYCLE VLOOP IF (IOR==-2 .AND. J/=VT%J1+1) CYCLE VLOOP IF (I<VT%I1+1 .OR. I>VT%I2) CYCLE VLOOP IF (K<VT%K1+1 .OR. K>VT%K2) CYCLE VLOOP ENDIF IF (ABS(IOR)==3) THEN IF (IOR== 3 .AND. K/=VT%K1 ) CYCLE VLOOP IF (IOR==-3 .AND. K/=VT%K1+1) CYCLE VLOOP IF (I<VT%I1+1 .OR. I>VT%I2) CYCLE VLOOP IF (J<VT%J1+1 .OR. J>VT%J2) CYCLE VLOOP ENDIF ! Check if there are over-lapping VENTs IF (VENT_FOUND) THEN WRITE(MESSAGE,'(A,I2,A,3I3,A,I3)') 'WARNING: Two VENTs overlap in MESH ',NM,', Cell',I,J,K,'. FDS rejects VENT ',VT%ORDINAL WRITE(0,'(/A/)') MESSAGE EXIT VLOOP ENDIF VENT_FOUND = .TRUE. ! Reassign the SURF index to be that of the VENT M%VENT_INDEX(IW) = N IBCX = VT%IBC M%AREA_ADJUST(IW) = VT%INPUT_AREA/VT%FDS_AREA IF (M%AREA_ADJUST(IW)==0._EB) M%AREA_ADJUST(IW) = 1._EB ! Set the velocity at each surface cell IF (SURFACE(IBCX)%VEL/=-999._EB) THEN M%UW0(IW) = SURFACE(IBCX)%VEL ELSE M%UW0(IW) = 0._EB ENDIF IF (SURFACE(IBCX)%VOLUME_FLUX /=-999._EB) M%UW0(IW) = SURFACE(IBCX)%VOLUME_FLUX/VT%TOTAL_INPUT_AREA IF (SURFACE(IBCX)%MASS_FLUX_TOTAL/=-999._EB) M%UW0(IW) = SURFACE(IBCX)%MASS_FLUX_TOTAL/RHOA*M%AREA_ADJUST(IW) ! Special velocity profiles IF (SURFACE(IBCX)%PROFILE==PARABOLIC) THEN SELECT CASE(ABS(IOR)) CASE(1) Y1 = M%Y(VT%J1) Y2 = M%Y(VT%J2) Z1 = M%Z(VT%K1) Z2 = M%Z(VT%K2) PY = 4._EB*(M%YC(J)-Y1)*(Y2-M%YC(J))/(Y2-Y1)**2 PZ = 4._EB*(M%ZC(K)-Z1)*(Z2-M%ZC(K))/(Z2-Z1)**2 M%UW0(IW) = M%UW0(IW)*PY*PZ CASE(2) X1 = M%X(VT%I1) X2 = M%X(VT%I2) Z1 = M%Z(VT%K1) Z2 = M%Z(VT%K2) PX = 4._EB*(M%XC(I)-X1)*(X2-M%XC(I))/(X2-X1)**2 PZ = 4._EB*(M%ZC(K)-Z1)*(Z2-M%ZC(K))/(Z2-Z1)**2 M%UW0(IW) = M%UW0(IW)*PX*PZ CASE(3) X1 = M%X(VT%I1) X2 = M%X(VT%I2) IF (CYLINDRICAL .AND. X1==0._EB) X1 = -X2 Y1 = M%Y(VT%J1) Y2 = M%Y(VT%J2) PX = 4._EB*(M%XC(I)-X1)*(X2-M%XC(I))/(X2-X1)**2 PY = 4._EB*(M%YC(J)-Y1)*(Y2-M%YC(J))/(Y2-Y1)**2 IF (CYLINDRICAL) THEN M%UW0(IW) = M%UW0(IW)*PX ELSE M%UW0(IW) = M%UW0(IW)*PX*PY ENDIF END SELECT ENDIF IF (SURFACE(IBCX)%PROFILE==ATMOSPHERIC) THEN Z1 = M%Z(VT%K1) M%UW0(IW) = M%UW0(IW)*((M%ZC(K)-Z1)/ SURFACE(IBCX)%Z0)**SURFACE(IBCX)%PLE ENDIF IF (SURFACE(IBCX)%PROFILE==ONED_PARABOLIC) THEN SELECT CASE(ABS(IOR)) CASE(1) Y1 = M%Y(VT%J1) Y2 = M%Y(VT%J2) PY = 4._EB*(M%YC(J)-Y1)*(Y2-M%YC(J))/(Y2-Y1)**2 M%UW0(IW) = M%UW0(IW)*PY CASE(2) X1 = M%X(VT%I1) X2 = M%X(VT%I2) PX = 4._EB*(M%XC(I)-X1)*(X2-M%XC(I))/(X2-X1)**2 M%UW0(IW) = M%UW0(IW)*PX CASE(3) X1 = M%X(VT%I1) X2 = M%X(VT%I2) Y1 = M%Y(VT%J1) Y2 = M%Y(VT%J2) PX = 4._EB*(M%XC(I)-X1)*(X2-M%XC(I))/(X2-X1)**2 PY = 4._EB*(M%YC(J)-Y1)*(Y2-M%YC(J))/(Y2-Y1)**2 M%UW0(IW) = M%UW0(IW)*PX*PY END SELECT ENDIF ! Check if fire spreads radially IF (VT%X0>-900._EB) THEN DIST = SQRT((M%XW(IW)-VT%X0)**2 +(M%YW(IW)-VT%Y0)**2 +(M%ZW(IW)-VT%Z0)**2) T_ACTIVATE = T_BEGIN+DIST/VT%FIRE_SPREAD_RATE ENDIF ! Miscellaneous settings IF (VT%BOUNDARY_TYPE==OPEN_BOUNDARY) THEN M%BOUNDARY_TYPE(IW) = OPEN_BOUNDARY IF (M%PRESSURE_ZONE_WALL(IW)>0) THEN WRITE(MESSAGE,'(A,I2,A)') 'ERROR: Pressure ZONE ',M%PRESSURE_ZONE_WALL(IW),' cannot have an OPEN boundary' CALL SHUTDOWN(MESSAGE) ENDIF ENDIF IF (VT%BOUNDARY_TYPE==MIRROR_BOUNDARY) M%BOUNDARY_TYPE(IW) = MIRROR_BOUNDARY IF (.NOT.VT%ACTIVATED) T_ACTIVATE = 1000000._EB M%IJKW(5,IW) = IBCX ENDDO VLOOP ! Set ignition time of each boundary cell IF (T_ACTIVATE<0._EB) THEN M%TW(IW) = SURFACE(IBCX)%T_IGNELSE M%TW(IW) = T_ACTIVATEENDIF ! Initialize solid temperature and densities SF => SURFACE(IBCX)IF (SF%THERMALLY_THICK) THEN WC => M%WALL(IW) ALLOCATE(WC%TMP_S(0:SF%N_CELLS+1),STAT=IZERO) CALL ChkMemErr('INIT','TMP_S',IZERO) WC%TMP_S(:) = SF%TMP_INNER ALLOCATE(WC%RHO_S(0:SF%N_CELLS+1,SF%N_MATL),STAT=IZERO) CALL ChkMemErr('INIT','RHO_S',IZERO) WC%RHO_S = 0._EB DO II=0,SF%N_CELLS+1 IL = SF%LAYER_INDEX(II) DO NN=1,SF%N_LAYER_MATL(IL) DO N=1,SF%N_MATL IF (SF%LAYER_MATL_INDEX(IL,NN)==SF%MATL_INDEX(N)) & WC%RHO_S(II,N) = SF%LAYER_MATL_FRAC(IL,NN)*SF%LAYER_DENSITY(IL) ENDDO ENDDO ENDDO IF (SF%SHRINK) THEN ALLOCATE(WC%LAYER_THICKNESS(SF%N_LAYERS),STAT=IZERO) CALL ChkMemErr('INIT','LAYER_THICKNESS',IZERO) WC%LAYER_THICKNESS = SF%LAYER_THICKNESS(1:SF%N_LAYERS) ALLOCATE(WC%N_LAYER_CELLS(SF%N_LAYERS),STAT=IZERO) CALL ChkMemErr('INIT','N_LAYER_CELLS',IZERO) WC%N_LAYER_CELLS = SF%N_LAYER_CELLS ALLOCATE(WC%X_S(0:SF%N_CELLS),STAT=IZERO) CALL ChkMemErr('INIT','X_S',IZERO) WC%X_S = SF%X_S ENDIF WC%SHRINKING = .FALSE. WC%BURNAWAY = .FALSE. M%TMP_F(IW) = SF%TMP_INNER M%TMP_B(IW) = SF%TMP_INNER M%TMP_W(IW) = SF%TMP_INNERENDIF ! Misc M%E_WALL(IW) = SF%EMISSIVITYM%NPPCW(IW) = SF%NPPC ! Number of particles per cellEND SUBROUTINE INIT_WALL_CELL SUBROUTINE OPEN_AND_CLOSE(T,NM)! Check to see if a cell or OBSTruction is to be created or removed, or a VENT activated of deactivatedUSE MEMORY_FUNCTIONS, ONLY : RE_ALLOCATE_STRINGSUSE CONTROL_VARIABLES, ONLY : CONTROLUSE DEVICE_VARIABLES, ONLY : DEVICEREAL(EB) :: TINTEGER :: N,II,JJ,KK,IW,IORINTEGER, INTENT(IN) :: NMLOGICAL :: CREATE_OBST,REMOVE_OBST,ACTIVATE_VENT,DEACTIVATE_VENTCHARACTER(12) :: SV_LABELTYPE (VENTS_TYPE), POINTER :: VT CALL POINT_TO_MESH(NM) ! Check to see if an obstacle is to be removed or createdOBST_LOOP: DO N=1,N_OBST OB=>OBSTRUCTION(N) IF (.NOT. OB%REMOVABLE) CYCLE OBST_LOOP CREATE_OBST = .FALSE. REMOVE_OBST = .FALSE. IF (OB%CONSUMABLE .AND. OB%MASS <= 0._EB) REMOVE_OBST = .TRUE. IF (OB%DEVC_INDEX > 0) THEN IF (DEVICE(OB%DEVC_INDEX)%CURRENT_STATE .EQV. DEVICE(OB%DEVC_INDEX)%PRIOR_STATE) CYCLE OBST_LOOP IF (DEVICE(OB%DEVC_INDEX)%CURRENT_STATE) THEN CREATE_OBST = .TRUE. ELSE REMOVE_OBST = .TRUE. ENDIF ELSEIF (OB%CTRL_INDEX > 0) THEN IF (CONTROL(OB%CTRL_INDEX)%CURRENT_STATE .EQV. CONTROL(OB%CTRL_INDEX)%PRIOR_STATE) CYCLE OBST_LOOP IF (CONTROL(OB%CTRL_INDEX)%CURRENT_STATE) THEN CREATE_OBST = .TRUE. ELSE REMOVE_OBST = .TRUE. ENDIF ENDIF SV_LABEL = 'null' IF (CREATE_OBST .AND. OB%HIDDEN) THEN OB%HIDDEN = .FALSE. SV_LABEL = 'SHOW_OBST' CALL CREATE_OR_REMOVE_OBST(NM,OB%I1+1,OB%I2,OB%J1+1,OB%J2,OB%K1+1,OB%K2,1,N) ENDIF IF (REMOVE_OBST .AND. (.NOT. OB%HIDDEN)) THEN OB%HIDDEN = .TRUE. SV_LABEL = 'HIDE_OBST' CALL CREATE_OR_REMOVE_OBST(NM,OB%I1+1,OB%I2,OB%J1+1,OB%J2,OB%K1+1,OB%K2,0,N) ENDIF ! Write a message to the Smokeview .smv file that the obstruction has been created or removed IF (SV_LABEL /= 'null') THEN IF (N_STRINGS+2>N_STRINGS_MAX) THEN CALL RE_ALLOCATE_STRINGS(NM) STRING => MESHES(NM)%STRING ENDIF N_STRINGS = N_STRINGS + 1 WRITE(STRING(N_STRINGS),'(A,I3)') SV_LABEL,NM N_STRINGS = N_STRINGS + 1 WRITE(STRING(N_STRINGS),'(I6,F10.2)') N,T ENDIFENDDO OBST_LOOP ! Check to see if a vent should be activated or deactivated VENT_LOOP: DO N=1,N_VENT VT => VENTS(N) ACTIVATE_VENT = .FALSE. DEACTIVATE_VENT = .FALSE. IF (VT%DEVC_INDEX > 0) THEN IF (DEVICE(VT%DEVC_INDEX)%CURRENT_STATE .EQV. DEVICE(VT%DEVC_INDEX)%PRIOR_STATE) CYCLE VENT_LOOP IF (DEVICE(VT%DEVC_INDEX)%CURRENT_STATE) THEN ACTIVATE_VENT = .TRUE. ELSE DEACTIVATE_VENT = .TRUE. ENDIF ELSEIF (VT%CTRL_INDEX > 0) THEN IF (CONTROL(VT%CTRL_INDEX)%CURRENT_STATE .EQV. CONTROL(VT%CTRL_INDEX)%PRIOR_STATE) CYCLE VENT_LOOP IF (CONTROL(VT%CTRL_INDEX)%CURRENT_STATE) THEN ACTIVATE_VENT = .TRUE. ELSE DEACTIVATE_VENT = .TRUE. ENDIF ENDIF IF (.NOT.ACTIVATE_VENT .AND. .NOT.DEACTIVATE_VENT) CYCLE VENT_LOOP ! Look through all boundary cells looking for those that conform to the given VENT SEARCH: DO IW=1,NWC II = IJKW(1,IW) JJ = IJKW(2,IW) KK = IJKW(3,IW) IOR = IJKW(4,IW) IF (IOR/=VT%IOR) CYCLE SEARCH SELECT CASE(ABS(IOR)) CASE(1) IF (IOR== 1 .AND. II/=VT%I1) CYCLE SEARCH IF (IOR==-1 .AND. II/=VT%I1+1) CYCLE SEARCH IF (JJ<VT%J1+1 .OR. JJ>VT%J2) CYCLE SEARCH IF (KK<VT%K1+1 .OR. KK>VT%K2) CYCLE SEARCH CASE(2) IF (IOR== 2 .AND. JJ/=VT%J1) CYCLE SEARCH IF (IOR==-2 .AND. JJ/=VT%J1+1) CYCLE SEARCH IF (II<VT%I1+1 .OR. II>VT%I2) CYCLE SEARCH IF (KK<VT%K1+1 .OR. KK>VT%K2) CYCLE SEARCH CASE(3) IF (IOR== 3 .AND. KK/=VT%K1) CYCLE SEARCH IF (IOR==-3 .AND. KK/=VT%K1+1) CYCLE SEARCH IF (II<VT%I1+1 .OR. II>VT%I2) CYCLE SEARCH IF (JJ<VT%J1+1 .OR. JJ>VT%J2) CYCLE SEARCH END SELECT IF (ACTIVATE_VENT) THEN TW(IW) = T ELSE TW(IW) = 1000000._EB ENDIF ENDDO SEARCH ! Write message to .smv file IF (ACTIVATE_VENT) SV_LABEL = 'OPEN_VENT' IF (DEACTIVATE_VENT) SV_LABEL = 'CLOSE_VENT' IF (N_STRINGS+2>N_STRINGS_MAX) THEN CALL RE_ALLOCATE_STRINGS(NM) STRING => MESHES(NM)%STRING ENDIF N_STRINGS = N_STRINGS + 1 WRITE(STRING(N_STRINGS),'(A,I3)') SV_LABEL,NM N_STRINGS = N_STRINGS + 1 WRITE(STRING(N_STRINGS),'(I6,F10.2)') N,TENDDO VENT_LOOP END SUBROUTINE OPEN_AND_CLOSE SUBROUTINE CREATE_OR_REMOVE_OBST(NM,I1,I2,J1,J2,K1,K2,CR_INDEX,OBST_INDEX)! Create or remove the obstruction whose CELLS (not nodes) are given by I1, I2, etc.USE GEOMETRY_FUNCTIONS, ONLY : BLOCK_CELLINTEGER :: I1,I2,J1,J2,K1,K2,I,J,K,IE,IW,IC,ICGINTEGER, INTENT(IN) :: NM,CR_INDEX,OBST_INDEXLOGICAL :: CREATE,REMOVE CALL POINT_TO_MESH(NM)REMOVE = .FALSE.CREATE = .FALSE.IF (CR_INDEX==0) REMOVE = .TRUE.IF (CR_INDEX==1) CREATE = .TRUE. ! Blank or unblank cells that make up the OBSTruction CALL BLOCK_CELL(NM,I1,I2,J1,J2,K1,K2,CR_INDEX,OBST_INDEX) ! Process the x boundaries of the OBSTructionDO K=K1,K2 DO J=J1,J2 ! Nullify and/or uncover wall cells on the x=x1 side of the OBSTruction IF (I1 > 1) THEN ICG = CELL_INDEX(I1-1,J,K) IW = WALL_INDEX(ICG,1) IF (REMOVE) BOUNDARY_TYPE(IW) = NULL_BOUNDARY IF (CREATE .AND. .NOT.SOLID(ICG)) CALL GET_BOUNDARY_TYPE( IW , IJKW(5,IW) , BOUNDARY_TYPE(IW) ) ENDIF IC = CELL_INDEX(I1,J,K) IW = WALL_INDEX(IC,-1) IF (IW > 0 .AND. REMOVE) CALL GET_BOUNDARY_TYPE( IW , IJKW(5,IW) , BOUNDARY_TYPE(IW) ) IF (CREATE) BOUNDARY_TYPE(IW) = NULL_BOUNDARY ! Nullify and/or uncover wall cells on the x=x2 side of the OBSTruction IF (I2 < IBAR) THEN ICG = CELL_INDEX(I2+1,J,K) IW = WALL_INDEX(ICG,-1) IF (REMOVE) BOUNDARY_TYPE(IW) = NULL_BOUNDARY IF (CREATE .AND. .NOT.SOLID(ICG)) CALL GET_BOUNDARY_TYPE( IW , IJKW(5,IW) , BOUNDARY_TYPE(IW) ) ENDIF IC = CELL_INDEX(I2,J,K) IW = WALL_INDEX(IC,1) IF (IW > 0 .AND. REMOVE) CALL GET_BOUNDARY_TYPE( IW , IJKW(5,IW) , BOUNDARY_TYPE(IW) ) IF (CREATE) BOUNDARY_TYPE(IW) = NULL_BOUNDARY ENDDOENDDO! Process the y boundaries of the OBSTructionDO K=K1,K2 DO I=I1,I2 ! Nullify and/or uncover wall cells on the y=y1 side of the OBSTruction IF (J1 > 1) THEN ICG = CELL_INDEX(I,J1-1,K) IW = WALL_INDEX(ICG,2) IF (REMOVE) BOUNDARY_TYPE(IW) = NULL_BOUNDARY IF (CREATE .AND. .NOT.SOLID(ICG)) CALL GET_BOUNDARY_TYPE( IW , IJKW(5,IW) , BOUNDARY_TYPE(IW) ) ENDIF IC = CELL_INDEX(I,J1,K) IW = WALL_INDEX(IC,-2) IF (IW > 0 .AND. REMOVE) CALL GET_BOUNDARY_TYPE( IW , IJKW(5,IW) , BOUNDARY_TYPE(IW) ) IF (CREATE) BOUNDARY_TYPE(IW) = NULL_BOUNDARY ! Nullify and/or uncover wall cells on the y=y2 side of the OBSTruction IF (J2 < JBAR) THEN ICG = CELL_INDEX(I,J2+1,K) IW = WALL_INDEX(I
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -