diff --git a/Source/dump.f90 b/Source/dump.f90 index eed206a2f95..f78500b8631 100644 --- a/Source/dump.f90 +++ b/Source/dump.f90 @@ -890,8 +890,9 @@ SUBROUTINE INITIALIZE_MESH_DUMPS(NM) USE COMP_FUNCTIONS, ONLY: CURRENT_TIME USE MEMORY_FUNCTIONS, ONLY: RE_ALLOCATE_STRINGS,CHKMEMERR USE RADCONS, ONLY: DLX,DLY,DLZ +USE TRAN, ONLY: GINV INTEGER, INTENT(IN) :: NM -INTEGER :: IOR,IZERO,I,J,K,N,I1B,I2B,IW,NN,NF,IP +INTEGER :: IOR,IZERO,I,J,K,N,I1B,I2B,IW,NN,NF,IP,OBST_INDEX,NOM,IC INTEGER :: NTSL LOGICAL, ALLOCATABLE, DIMENSION(:,:) :: PAINT_FACE REAL(EB) :: TNOW,NRM @@ -899,8 +900,10 @@ SUBROUTINE INITIALIZE_MESH_DUMPS(NM) LOGICAL, ALLOCATABLE, DIMENSION(:,:) :: OUT_OF_MESH CHARACTER(LEN=1024) :: SLICEPARMS, SLICELABEL TYPE(PATCH_TYPE), POINTER :: PA +TYPE(MESH_TYPE), POINTER :: M4 INTEGER :: CC_VAL,NSTEPS INTEGER :: SMOKE3D_16_COMPRESS, SMOKE3D_16_VERSION +LOGICAL :: OVERLAPPING_X,OVERLAPPING_Y,OVERLAPPING_Z TYPE (BOUNDARY_COORD_TYPE), POINTER :: BC TYPE (RAD_FILE_TYPE), POINTER :: RF @@ -1227,8 +1230,9 @@ SUBROUTINE INITIALIZE_MESH_DUMPS(NM) ! Count and allocate the PATCHes - M%N_PATCH = 0 - DO N=0,M%N_OBST + M%N_PATCH = M%N_EXTERIOR_PATCH + + DO N=1,M%N_OBST OB=>M%OBSTRUCTION(N) DO IOR=-3,3 IF (.NOT.OB%SHOW_BNDF(IOR)) PAINT_FACE(N,IOR) = .FALSE. @@ -1240,53 +1244,108 @@ SUBROUTINE INITIALIZE_MESH_DUMPS(NM) ALLOCATE(M%PATCH(M%N_PATCH),STAT=IZERO) CALL ChkMemErr('DUMP','PATCH',IZERO) - ! Assign coordinate indices for each PATCH + ! Assign coordinate indices for PATCHes that live on the exterior boundary of the mesh - IP = 0 M%N_BNDF_POINTS = 0 - DO N=0,M%N_OBST - OB=>M%OBSTRUCTION(N) + + DO IP=1,M%N_EXTERIOR_PATCH + PA => M%PATCH(IP) + M%PATCH(IP) = M%EXTERIOR_PATCH(IP) + M%N_BNDF_POINTS = M%N_BNDF_POINTS + (PA%IG2-PA%IG1+1)*(PA%JG2-PA%JG1+1)*(PA%KG2-PA%KG1+1) + PA%MESH_INDEX = NM + ENDDO + + ! Assign coordinate indices for PATCHes that live on the boundaries of obstructions + + IP = M%N_EXTERIOR_PATCH + + DO OBST_INDEX=1,M%N_OBST + OB => M%OBSTRUCTION(OBST_INDEX) DO IOR=-3,3 - IF (.NOT.PAINT_FACE(N,IOR)) CYCLE + IF (.NOT.PAINT_FACE(OBST_INDEX,IOR)) CYCLE IP = IP + 1 PA => M%PATCH(IP) - IF (N==0) THEN - PA%I1 = 0 ; PA%IG1 = 1 - PA%I2 = IBAR ; PA%IG2 = IBAR - PA%J1 = 0 ; PA%JG1 = 1 - PA%J2 = JBAR ; PA%JG2 = JBAR - PA%K1 = 0 ; PA%KG1 = 1 - PA%K2 = KBAR ; PA%KG2 = KBAR - SELECT CASE(IOR) - CASE( 1) ; PA%I2 = PA%I1 ; PA%IG2 = PA%IG1 - CASE(-1) ; PA%I1 = PA%I2 ; PA%IG1 = PA%IG2 - CASE( 2) ; PA%J2 = PA%J1 ; PA%JG2 = PA%JG1 - CASE(-2) ; PA%J1 = PA%J2 ; PA%JG1 = PA%JG2 - CASE( 3) ; PA%K2 = PA%K1 ; PA%KG2 = PA%KG1 - CASE(-3) ; PA%K1 = PA%K2 ; PA%KG1 = PA%KG2 - END SELECT - ELSE - PA%I1 = OB%I1 ; PA%IG1 = OB%I1+1 - PA%I2 = OB%I2 ; PA%IG2 = OB%I2 - PA%J1 = OB%J1 ; PA%JG1 = OB%J1+1 - PA%J2 = OB%J2 ; PA%JG2 = OB%J2 - PA%K1 = OB%K1 ; PA%KG1 = OB%K1+1 - PA%K2 = OB%K2 ; PA%KG2 = OB%K2 - SELECT CASE(IOR) - CASE(-1) ; PA%I2 = PA%I1 ; PA%IG1=PA%IG1-1 ; PA%IG2 = PA%IG1 - CASE( 1) ; PA%I1 = PA%I2 ; PA%IG2=PA%IG2+1 ; PA%IG1 = PA%IG2 - CASE(-2) ; PA%J2 = PA%J1 ; PA%JG1=PA%JG1-1 ; PA%JG2 = PA%JG1 - CASE( 2) ; PA%J1 = PA%J2 ; PA%JG2=PA%JG2+1 ; PA%JG1 = PA%JG2 - CASE(-3) ; PA%K2 = PA%K1 ; PA%KG1=PA%KG1-1 ; PA%KG2 = PA%KG1 - CASE( 3) ; PA%K1 = PA%K2 ; PA%KG2=PA%KG2+1 ; PA%KG1 = PA%KG2 - END SELECT - ENDIF + PA%I1 = OB%I1 ; PA%IG1 = OB%I1+1 + PA%I2 = OB%I2 ; PA%IG2 = OB%I2 + PA%J1 = OB%J1 ; PA%JG1 = OB%J1+1 + PA%J2 = OB%J2 ; PA%JG2 = OB%J2 + PA%K1 = OB%K1 ; PA%KG1 = OB%K1+1 + PA%K2 = OB%K2 ; PA%KG2 = OB%K2 + SELECT CASE(IOR) + CASE(-1) ; PA%I2 = PA%I1 ; PA%IG1=PA%IG1-1 ; PA%IG2 = PA%IG1 + CASE( 1) ; PA%I1 = PA%I2 ; PA%IG2=PA%IG2+1 ; PA%IG1 = PA%IG2 + CASE(-2) ; PA%J2 = PA%J1 ; PA%JG1=PA%JG1-1 ; PA%JG2 = PA%JG1 + CASE( 2) ; PA%J1 = PA%J2 ; PA%JG2=PA%JG2+1 ; PA%JG1 = PA%JG2 + CASE(-3) ; PA%K2 = PA%K1 ; PA%KG1=PA%KG1-1 ; PA%KG2 = PA%KG1 + CASE( 3) ; PA%K1 = PA%K2 ; PA%KG2=PA%KG2+1 ; PA%KG1 = PA%KG2 + END SELECT PA%IOR = IOR - PA%OBST_INDEX = N + PA%OBST_INDEX = OBST_INDEX + PA%MESH_INDEX = NM M%N_BNDF_POINTS = M%N_BNDF_POINTS + (PA%IG2-PA%IG1+1)*(PA%JG2-PA%JG1+1)*(PA%KG2-PA%KG1+1) ENDDO ENDDO + ! Assign coordinate indices for PATCHes that live on the boundaries of obstructions in other meshes + + DO N=1,M%N_NEIGHBORING_MESHES + NOM = M%NEIGHBORING_MESH(N) + IF (NM==NOM) CYCLE + M4 => MESHES(NOM) + OBST_LOOP: DO OBST_INDEX=1,M4%N_OBST + IOR=0 ; OVERLAPPING_X=.TRUE. ; OVERLAPPING_Y=.TRUE. ; OVERLAPPING_Z=.TRUE. + OB => M4%OBSTRUCTION(OBST_INDEX) + IF (OB%I1==OB%I2 .OR. OB%J1==OB%J2 .OR. OB%K1==OB%K2) CYCLE OBST_LOOP + IF (M%XS>OB%X2+MESH_SEPARATION_DISTANCE .OR. M%XFOB%Y2+MESH_SEPARATION_DISTANCE .OR. M%YFOB%Z2+MESH_SEPARATION_DISTANCE .OR. M%ZFSIZE(M%PATCH)) CALL REALLOCATE_PATCH(NM,SIZE(M%PATCH),SIZE(M%PATCH)+10) + PA => M%PATCH(M%N_PATCH) + PA%I1 = MIN(M%IBAR,MAX(0,NINT( GINV(OB%X1-M%XS,1,NM)*RDXI ))) ; PA%IG1 = PA%I1+1 + PA%I2 = MIN(M%IBAR,MAX(0,NINT( GINV(OB%X2-M%XS,1,NM)*RDXI ))) ; PA%IG2 = PA%I2 + PA%J1 = MIN(M%JBAR,MAX(0,NINT( GINV(OB%Y1-M%YS,2,NM)*RDETA ))) ; PA%JG1 = PA%J1+1 + PA%J2 = MIN(M%JBAR,MAX(0,NINT( GINV(OB%Y2-M%YS,2,NM)*RDETA ))) ; PA%JG2 = PA%J2 + PA%K1 = MIN(M%KBAR,MAX(0,NINT( GINV(OB%Z1-M%ZS,3,NM)*RDZETA ))) ; PA%KG1 = PA%K1+1 + PA%K2 = MIN(M%KBAR,MAX(0,NINT( GINV(OB%Z2-M%ZS,3,NM)*RDZETA ))) ; PA%KG2 = PA%K2 + SELECT CASE(IOR) + CASE(-1) ; PA%I1 = M%IBAR ; PA%I2 = PA%I1 ; PA%IG1 = PA%I1 ; PA%IG2 = PA%IG1 + CASE( 1) ; PA%I1 = 0 ; PA%I2 = PA%I1 ; PA%IG1 = PA%I1+1 ; PA%IG2 = PA%IG1 + CASE(-2) ; PA%J1 = M%JBAR ; PA%J2 = PA%J1 ; PA%JG1 = PA%J1 ; PA%JG2 = PA%JG1 + CASE( 2) ; PA%J1 = 0 ; PA%J2 = PA%J1 ; PA%JG1 = PA%J1+1 ; PA%JG2 = PA%JG1 + CASE(-3) ; PA%K1 = M%KBAR ; PA%K2 = PA%K1 ; PA%KG1 = PA%K1 ; PA%KG2 = PA%KG1 + CASE( 3) ; PA%K1 = 0 ; PA%K2 = PA%K1 ; PA%KG1 = PA%K1+1 ; PA%KG2 = PA%KG1 + END SELECT + IF (ABS(IOR)==1 .AND. (PA%J1==PA%J2 .OR. PA%K1==PA%K2)) THEN ; M%N_PATCH=M%N_PATCH-1 ; CYCLE OBST_LOOP ; ENDIF + IF (ABS(IOR)==2 .AND. (PA%I1==PA%I2 .OR. PA%K1==PA%K2)) THEN ; M%N_PATCH=M%N_PATCH-1 ; CYCLE OBST_LOOP ; ENDIF + IF (ABS(IOR)==3 .AND. (PA%I1==PA%I2 .OR. PA%J1==PA%J2)) THEN ; M%N_PATCH=M%N_PATCH-1 ; CYCLE OBST_LOOP ; ENDIF + DO K=PA%KG1,PA%KG2 + DO J=PA%JG1,PA%JG2 + DO I=PA%IG1,PA%IG2 + IC = M%CELL_INDEX(I,J,K) + IF ( .NOT.M%CELL(IC)%SOLID .OR. & + (M%CELL(IC)%SOLID .AND. .NOT.M%OBSTRUCTION(M%CELL(IC)%OBST_INDEX)%REMOVABLE) ) THEN + M%N_PATCH=M%N_PATCH-1 + CYCLE OBST_LOOP + ENDIF + ENDDO + ENDDO + ENDDO + PA%IOR = IOR + PA%OBST_INDEX = OBST_INDEX + PA%MESH_INDEX = NOM + M%N_BNDF_POINTS = M%N_BNDF_POINTS + (PA%IG2-PA%IG1+1)*(PA%JG2-PA%JG1+1)*(PA%KG2-PA%KG1+1) + ENDDO OBST_LOOP + ENDDO + DEALLOCATE(PAINT_FACE) ENDIF CREATE_PATCHES @@ -1328,7 +1387,7 @@ SUBROUTINE INITIALIZE_MESH_DUMPS(NM) WRITE(LU_BNDF(NF,NM)) M%N_PATCH DO IP=1,M%N_PATCH PA=>M%PATCH(IP) - WRITE(LU_BNDF(NF,NM)) PA%I1,PA%I2,PA%J1,PA%J2,PA%K1,PA%K2,PA%IOR,PA%OBST_INDEX,NM + WRITE(LU_BNDF(NF,NM)) PA%I1,PA%I2,PA%J1,PA%J2,PA%K1,PA%K2,PA%IOR,PA%OBST_INDEX,PA%MESH_INDEX ENDDO CLOSE(LU_BNDF(NF,NM)) ENDIF @@ -1413,18 +1472,42 @@ SUBROUTINE INITIALIZE_MESH_DUMPS(NM) END SUBROUTINE INITIALIZE_MESH_DUMPS +!> \brief Re-allocate the derived type array P_ZONE +!> \param NM Mesh number +!> \param N1 Current size of array +!> \param N2 New size of array + +SUBROUTINE REALLOCATE_PATCH(NM,N1,N2) + +INTEGER, INTENT(IN) :: N1,N2,NM +TYPE (PATCH_TYPE), DIMENSION(:), ALLOCATABLE :: PATCH_DUMMY +TYPE (MESH_TYPE), POINTER :: M + +M => MESHES(NM) + +ALLOCATE(PATCH_DUMMY(1:N2)) +PATCH_DUMMY(1:N1) = M%PATCH(1:N1) +DEALLOCATE(M%PATCH) +ALLOCATE(M%PATCH(1:N2)) +M%PATCH(1:N2) = PATCH_DUMMY(1:N2) +DEALLOCATE(PATCH_DUMMY) + +END SUBROUTINE REALLOCATE_PATCH + + +!> \brief Parallel write of the Smokeview (.smv) file + SUBROUTINE WRITE_SMOKEVIEW_FILE USE MATH_FUNCTIONS, ONLY: CROSS_PRODUCT USE MEMORY_FUNCTIONS, ONLY : CHKMEMERR USE COMP_FUNCTIONS, ONLY: SHUTDOWN,GET_FILE_NUMBER -USE GEOMETRY_FUNCTIONS, ONLY: INTERIOR +USE GEOMETRY_FUNCTIONS, ONLY: INTERIOR,SEARCH_OTHER_MESHES USE HVAC_ROUTINES, ONLY: N_DUCT_QUANTITY,N_NODE_QUANTITY, DUCT_QUANTITY_ARRAY,NODE_QUANTITY_ARRAY USE TRAN, ONLY: TRAN_TYPE,TRANS USE MISC_FUNCTIONS, ONLY : ACCUMULATE_STRING -INTEGER :: N,NN,I,J,K,NM,NX,NY,NZ,NIN,NXL,NYL,NZL,NDV,NDVDIM,COLOR_INDEX,IZERO,STATE_INDEX,SURF_INDEX,& +INTEGER :: N,NN,I,J,K,NM,NX,NY,NZ,NIN,NXL,NYL,NZL,COLOR_INDEX,IZERO,STATE_INDEX,SURF_INDEX,& TYPE_INDEX,HI1,HI2,VI1,VI2,FACE_INDEX,VRGB(3),N_CVENT -INTEGER, ALLOCATABLE, DIMENSION(:) :: IDV1,IDV2,JDV1,JDV2,KDV1,KDV2,DUMMY_VENT_INDEX INTEGER, ALLOCATABLE, DIMENSION(:,:,:) :: VENT_INDICES REAL(EB) :: X1,Y1,Z1,X2,Y2,Z2,XX,YY,ZZ,PERT1(4),PERT2(4),XMIN,YMIN,ZMIN,XA,YA,ZA TYPE SEGMENT_TYPE @@ -1439,8 +1522,8 @@ SUBROUTINE WRITE_SMOKEVIEW_FILE LOGICAL :: EX, FOUND_GEOM CHARACTER(MESSAGE_LENGTH) :: MESSAGE TYPE(GEOMETRY_TYPE), POINTER :: G=>NULL() -INTEGER :: IG, IS_TERRAIN_INT -INTEGER :: II, JJ +INTEGER :: IG,IS_TERRAIN_INT +INTEGER :: II,JJ,IIO,JJO,KKO,NOM INTEGER :: N_NODE_OUT, N_DUCT_OUT CHARACTER(LABEL_LENGTH) :: DEV_QUAN, HVAC_LABEL, OBST_LABEL TYPE (MPI_STATUS) :: STATUS @@ -1449,6 +1532,7 @@ SUBROUTINE WRITE_SMOKEVIEW_FILE CHARACTER(LEN=STRING_LENGTH) :: MYSTR CHARACTER(LEN=:), ALLOCATABLE :: SMVSTR INTEGER :: OFFSET=0, SMVSTR_T_LEN=0, SMVSTR_USE_LEN=0, IERR +TYPE (PATCH_TYPE), POINTER :: EP ! If this is a RESTART case but an old .smv file does not exist, shutdown with an ERROR. @@ -2155,20 +2239,10 @@ SUBROUTINE WRITE_SMOKEVIEW_FILE IF (VT%RADIUS>0._EB) N_CVENT=N_CVENT+1 ENDDO - ! Replace vents on exterior mesh boundary with "dummy" vents to avoid overlap conflict in Smokeview - - NDV = 0 - NDVDIM = 10*(6+N_VENT_TOTAL) - ALLOCATE(DUMMY_VENT_INDEX(NDVDIM)) - ALLOCATE(IDV1(NDVDIM)) - ALLOCATE(IDV2(NDVDIM)) - ALLOCATE(JDV1(NDVDIM)) - ALLOCATE(JDV2(NDVDIM)) - ALLOCATE(KDV1(NDVDIM)) - ALLOCATE(KDV2(NDVDIM)) - ALLOCATE(VENT_INDICES(MAX(M%IBAR,M%JBAR),MAX(M%JBAR,M%KBAR),6)) + ! Create EXTERIOR_PATCHes with which Smokeview colors, textures, or contours exterior mesh boundaries. - VENT_INDICES = 0 + ALLOCATE(M%EXTERIOR_PATCH(10*(6+N_VENT_TOTAL))) ; M%N_EXTERIOR_PATCH = 0 + ALLOCATE(VENT_INDICES(MAX(M%IBAR,M%JBAR),MAX(M%JBAR,M%KBAR),6)) ; VENT_INDICES = 0 VENT_LOOP: DO N=1,M%N_VENT @@ -2205,9 +2279,9 @@ SUBROUTINE WRITE_SMOKEVIEW_FILE END SELECT IF (VT%BOUNDARY_TYPE==MIRROR_BOUNDARY .OR. & - VT%BOUNDARY_TYPE==OPEN_BOUNDARY .OR. & - VT%BOUNDARY_TYPE==PERIODIC_BOUNDARY .OR. & - VT%TYPE_INDICATOR==2) THEN + VT%BOUNDARY_TYPE==OPEN_BOUNDARY .OR. & + VT%BOUNDARY_TYPE==PERIODIC_BOUNDARY .OR. & + VT%TYPE_INDICATOR==2) THEN ! Render this vent invisible in Smokeview WHERE (VENT_INDICES(HI1:HI2,VI1:VI2,FACE_INDEX)==0) VENT_INDICES(HI1:HI2,VI1:VI2,FACE_INDEX) = -1 ELSE ! Make solid color vents invisible (they will be replaced by dummy vents) WHERE (VENT_INDICES(HI1:HI2,VI1:VI2,FACE_INDEX)==0) VENT_INDICES(HI1:HI2,VI1:VI2,FACE_INDEX) = N @@ -2218,62 +2292,63 @@ SUBROUTINE WRITE_SMOKEVIEW_FILE ENDDO VENT_LOOP - ! Look for interpolated meshes and ensure that dummy vents are not drawn there + ! Look for interpolated mesh boundaries and ensure that Smokeview leaves these blank (VENT_INDICES=-1). DO K=1,M%KBAR - J_LOOP1: DO J=1,M%JBAR + DO J=1,M%JBAR YY = 0.5_EB*(M%Y(J)+M%Y(J-1)) ZZ = 0.5_EB*(M%Z(K)+M%Z(K-1)) XX = M%X(0) - 0.001_EB*M%DX(0) - IF (INTERIOR(XX,YY,ZZ) .AND. & - (.NOT.M%CELL(M%CELL_INDEX(0,J,K))%SOLID .OR. VENT_INDICES(J,K,1)<1)) VENT_INDICES(J,K,1)=-1 + CALL SEARCH_OTHER_MESHES(XX,YY,ZZ,NOM,IIO,JJO,KKO) + IF (NOM>0 .AND. VENT_INDICES(J,K,1)<1) VENT_INDICES(J,K,1)=-1 XX = M%X(M%IBAR) + 0.001_EB*M%DX(M%IBAR) - IF (INTERIOR(XX,YY,ZZ) .AND. & - (.NOT.M%CELL(M%CELL_INDEX(M%IBAR+1,J,K))%SOLID .OR. VENT_INDICES(J,K,2)<1)) VENT_INDICES(J,K,2)=-1 - ENDDO J_LOOP1 + CALL SEARCH_OTHER_MESHES(XX,YY,ZZ,NOM,IIO,JJO,KKO) + IF (NOM>0 .AND. VENT_INDICES(J,K,2)<1) VENT_INDICES(J,K,2)=-1 + ENDDO ENDDO DO K=1,M%KBAR - I_LOOP1: DO I=1,M%IBAR + DO I=1,M%IBAR XX = 0.5_EB*(M%X(I)+M%X(I-1)) ZZ = 0.5_EB*(M%Z(K)+M%Z(K-1)) YY = M%Y(0) - 0.001_EB*M%DY(0) - IF (INTERIOR(XX,YY,ZZ) .AND. & - (.NOT.M%CELL(M%CELL_INDEX(I,0,K))%SOLID .OR. VENT_INDICES(I,K,3)<1)) VENT_INDICES(I,K,3)=-1 + CALL SEARCH_OTHER_MESHES(XX,YY,ZZ,NOM,IIO,JJO,KKO) + IF (NOM>0 .AND. VENT_INDICES(I,K,3)<1) VENT_INDICES(I,K,3)=-1 YY = M%Y(M%JBAR) + 0.001_EB*M%DY(M%JBAR) - IF (INTERIOR(XX,YY,ZZ) .AND. & - (.NOT.M%CELL(M%CELL_INDEX(I,M%JBAR+1,K))%SOLID .OR. VENT_INDICES(I,K,4)<1)) VENT_INDICES(I,K,4)=-1 - ENDDO I_LOOP1 + CALL SEARCH_OTHER_MESHES(XX,YY,ZZ,NOM,IIO,JJO,KKO) + IF (NOM>0 .AND. VENT_INDICES(I,K,4)<1) VENT_INDICES(I,K,4)=-1 + ENDDO ENDDO DO J=1,M%JBAR - I_LOOP2: DO I=1,M%IBAR + DO I=1,M%IBAR XX = 0.5_EB*(M%X(I)+M%X(I-1)) YY = 0.5_EB*(M%Y(J)+M%Y(J-1)) ZZ = M%Z(0) - 0.001_EB*M%DZ(0) - IF (INTERIOR(XX,YY,ZZ) .AND. & - (.NOT.M%CELL(M%CELL_INDEX(I,J,0))%SOLID .OR. VENT_INDICES(I,J,5)<1)) VENT_INDICES(I,J,5)=-1 + CALL SEARCH_OTHER_MESHES(XX,YY,ZZ,NOM,IIO,JJO,KKO) + IF (NOM>0 .AND. VENT_INDICES(I,J,5)<1) VENT_INDICES(I,J,5)=-1 ZZ = M%Z(M%KBAR) + 0.001_EB*M%DZ(M%KBAR) - IF (INTERIOR(XX,YY,ZZ) .AND. & - (.NOT.M%CELL(M%CELL_INDEX(I,J,M%KBAR+1))%SOLID .OR. VENT_INDICES(I,J,6)<1)) VENT_INDICES(I,J,6)=-1 - ENDDO I_LOOP2 + CALL SEARCH_OTHER_MESHES(XX,YY,ZZ,NOM,IIO,JJO,KKO) + IF (NOM>0 .AND. VENT_INDICES(I,J,6)<1) VENT_INDICES(I,J,6)=-1 + ENDDO ENDDO - ! Create dummy vents to fill in areas around actual specified vents + ! Create EXTERIOR_PATCHes to fill in areas around actual specified vents - CALL DUMMY_VENTS(1,M%JBAR,M%KBAR,JDV1,JDV2,KDV1,KDV2,0 ,IDV1,IDV2) - CALL DUMMY_VENTS(2,M%JBAR,M%KBAR,JDV1,JDV2,KDV1,KDV2,M%IBAR,IDV1,IDV2) - CALL DUMMY_VENTS(3,M%IBAR,M%KBAR,IDV1,IDV2,KDV1,KDV2,0 ,JDV1,JDV2) - CALL DUMMY_VENTS(4,M%IBAR,M%KBAR,IDV1,IDV2,KDV1,KDV2,M%JBAR,JDV1,JDV2) - CALL DUMMY_VENTS(5,M%IBAR,M%JBAR,IDV1,IDV2,JDV1,JDV2,0 ,KDV1,KDV2) - CALL DUMMY_VENTS(6,M%IBAR,M%JBAR,IDV1,IDV2,JDV1,JDV2,M%KBAR,KDV1,KDV2) + CALL DUMMY_VENTS(1,M%JBAR,M%KBAR) + CALL DUMMY_VENTS(2,M%JBAR,M%KBAR) + CALL DUMMY_VENTS(3,M%IBAR,M%KBAR) + CALL DUMMY_VENTS(4,M%IBAR,M%KBAR) + CALL DUMMY_VENTS(5,M%IBAR,M%JBAR) + CALL DUMMY_VENTS(6,M%IBAR,M%JBAR) DEALLOCATE(VENT_INDICES) ! Write out information about vents to Smokeview file + CALL EOL WRITE(MYSTR,'(A)') 'VENT'; CALL ADDSTR - WRITE(MYSTR,'(2I5)') M%N_VENT-N_CVENT+NDV,NDV; CALL ADDSTR + WRITE(MYSTR,'(2I5)') M%N_VENT-N_CVENT+M%N_EXTERIOR_PATCH,M%N_EXTERIOR_PATCH; CALL ADDSTR DO N=1,M%N_VENT VT=>M%VENTS(N) @@ -2282,11 +2357,12 @@ SUBROUTINE WRITE_SMOKEVIEW_FILE VT%TEXTURE(1),VT%TEXTURE(2),VT%TEXTURE(3); CALL ADDSTR ENDDO - DO N=1,NDV + DO N=1,M%N_EXTERIOR_PATCH SURF_INDEX = DEFAULT_SURF_INDEX - IF (DUMMY_VENT_INDEX(N)>0) SURF_INDEX=M%VENTS(DUMMY_VENT_INDEX(N))%SURF_INDEX - WRITE(MYSTR,'(6F14.5,I6,I4)') M%X(IDV1(N)),M%X(IDV2(N)),M%Y(JDV1(N)),M%Y(JDV2(N)), & - M%Z(KDV1(N)),M%Z(KDV2(N)),M%N_VENT+N,SURF_INDEX; CALL ADDSTR + EP => M%EXTERIOR_PATCH(N) + IF (EP%VENT_INDEX>0) SURF_INDEX = M%VENTS(EP%VENT_INDEX)%SURF_INDEX + WRITE(MYSTR,'(6F14.5,I6,I4)') M%X(EP%I1),M%X(EP%I2),M%Y(EP%J1),M%Y(EP%J2), & + M%Z(EP%K1),M%Z(EP%K2),M%N_VENT+N,SURF_INDEX; CALL ADDSTR ENDDO DO N=1,M%N_VENT @@ -2308,28 +2384,23 @@ SUBROUTINE WRITE_SMOKEVIEW_FILE REAL(VT%RGB,FB)/255._FB,VT%TRANSPARENCY,' ! ',VT%IOR; CALL ADDSTR ENDIF ENDDO - DO N=1,NDV + + DO N=1,M%N_EXTERIOR_PATCH COLOR_INDEX = 99 TYPE_INDEX = 0 VRGB = -1 - IF (DUMMY_VENT_INDEX(N)>0) VRGB = M%VENTS(DUMMY_VENT_INDEX(N))%RGB + EP => M%EXTERIOR_PATCH(N) + IF (EP%VENT_INDEX>0) VRGB = M%VENTS(EP%VENT_INDEX)%RGB IF (VRGB(1)<0) THEN - WRITE(MYSTR,'(8I5)') IDV1(N),IDV2(N),JDV1(N),JDV2(N),KDV1(N),KDV2(N),COLOR_INDEX,TYPE_INDEX; CALL ADDSTR + WRITE(MYSTR,'(8I5)') EP%I1,EP%I2,EP%J1,EP%J2,EP%K1,EP%K2,COLOR_INDEX,TYPE_INDEX; CALL ADDSTR ELSE - WRITE(MYSTR,'(8I5,4F13.5)') IDV1(N),IDV2(N),JDV1(N),JDV2(N),KDV1(N),KDV2(N),COLOR_INDEX,TYPE_INDEX, & + WRITE(MYSTR,'(8I5,4F13.5)') EP%I1,EP%I2,EP%J1,EP%J2,EP%K1,EP%K2,COLOR_INDEX,TYPE_INDEX, & REAL(VRGB,FB)/255._FB,1._EB; CALL ADDSTR ENDIF ENDDO - DEALLOCATE(IDV1) - DEALLOCATE(IDV2) - DEALLOCATE(JDV1) - DEALLOCATE(JDV2) - DEALLOCATE(KDV1) - DEALLOCATE(KDV2) - DEALLOCATE(DUMMY_VENT_INDEX) - ! Write out information about circular vents to Smokeview file + CALL EOL WRITE(MYSTR,'(A)') 'CVENT'; CALL ADDSTR WRITE(MYSTR,'(1I5)') N_CVENT; CALL ADDSTR @@ -2363,6 +2434,7 @@ SUBROUTINE WRITE_SMOKEVIEW_FILE ENDDO MESH_LOOP ! Write the .smv file + CALL MPI_FILE_DELETE(FN_SMV, MPI_INFO_NULL, IERR) CALL MPI_EXSCAN(SMVSTR_USE_LEN,OFFSET,1,MPI_INTEGER,MPI_SUM,MPI_COMM_WORLD,IERR) CALL MPI_FILE_OPEN(MPI_COMM_WORLD,FN_SMV,MPI_MODE_WRONLY+MPI_MODE_CREATE,MPI_INFO_NULL,SMVFILE_HANDLE,IERR) @@ -2374,33 +2446,29 @@ SUBROUTINE WRITE_SMOKEVIEW_FILE CONTAINS + !> \brief Accumulate string wrapper. + SUBROUTINE ADDSTR CALL ACCUMULATE_STRING(STRING_LENGTH,MYSTR,SMVSTR,SMVSTR_T_LEN,SMVSTR_USE_LEN) END SUBROUTINE ADDSTR + !> \brief End of line wrapper. + SUBROUTINE EOL MYSTR=' '; CALL ACCUMULATE_STRING(STRING_LENGTH,MYSTR,SMVSTR,SMVSTR_T_LEN,SMVSTR_USE_LEN) END SUBROUTINE EOL -!> \brief For exterior mesh face, FI, create "dummy" vent patches for Smokeview -!> + +!> \brief For exterior mesh face, FI, create EXTERIOR_PATCHes for Smokeview !> \param FI Face Index, 1-6, where 1 refers to lower \f$ x \f$ mesh boundary, 2 upper, etc. !> \param N1 Number of cells in the first coordinate direction !> \param N2 Number of cells in the second coordinate direction -!> \param IVV1 Lower indices of dummy vents for the first coordinate direction -!> \param IVV2 Upper indices of dummy vents for the first coordinate direction -!> \param JVV1 Lower indices of dummy vents for the second coordinate direction -!> \param JVV2 Upper indices of dummy vents for the second coordinate direction -!> \param N3 Index of the vent plane -!> \param KVV1 Lower indices of dummy vents for the vent plane, KVV1=KVV2=N3 -!> \param KVV2 Upper indices of dummy vents for the vent plane, KVV1=KVV2=N3 - -SUBROUTINE DUMMY_VENTS(FI,N1,N2,IVV1,IVV2,JVV1,JVV2,N3,KVV1,KVV2) - -INTEGER, INTENT(IN) :: N1,N2,N3,FI -INTEGER, INTENT(INOUT), DIMENSION(NDVDIM) :: IVV1,IVV2,JVV1,JVV2,KVV1,KVV2 + +SUBROUTINE DUMMY_VENTS(FI,N1,N2) + +INTEGER, INTENT(IN) :: N1,N2,FI INTEGER :: I,J,II,JJ,ISTP,JSTP,VENT_INDEX JLOOP: DO J=1,N2 @@ -2427,15 +2495,25 @@ SUBROUTINE DUMMY_VENTS(FI,N1,N2,IVV1,IVV2,JVV1,JVV2,N3,KVV1,KVV2) ENDDO JJLOOP2 ENDDO IILOOP - NDV = NDV + 1 VENT_INDICES(I:ISTP,J:JSTP,FI) = -1 - IVV1(NDV) = I-1 - IVV2(NDV) = ISTP - JVV1(NDV) = J-1 - JVV2(NDV) = JSTP - KVV1(NDV) = N3 - KVV2(NDV) = N3 - DUMMY_VENT_INDEX(NDV) = VENT_INDEX + + M%N_EXTERIOR_PATCH = M%N_EXTERIOR_PATCH + 1 + EP => M%EXTERIOR_PATCH(M%N_EXTERIOR_PATCH) + SELECT CASE(FI) + CASE (1) ; EP%I1=0 ; EP%I2=0 ; EP%J1=I-1 ; EP%J2=ISTP ; EP%K1=J-1 ; EP%K2=JSTP ; EP%IOR= 1 + EP%IG1=1 ; EP%IG2=1 ; EP%JG1=I ; EP%JG2=ISTP; EP%KG1=J ; EP%KG2=JSTP + CASE (2) ; EP%I1=M%IBAR ; EP%I2=M%IBAR ; EP%J1=I-1 ; EP%J2=ISTP ; EP%K1=J-1 ; EP%K2=JSTP ; EP%IOR=-1 + EP%IG1=EP%I1 ; EP%IG2=EP%I2 ; EP%JG1=I ; EP%JG2=ISTP; EP%KG1=J ; EP%KG2=JSTP + CASE (3) ; EP%J1=0 ; EP%J2=0 ; EP%I1=I-1 ; EP%I2=ISTP ; EP%K1=J-1 ; EP%K2=JSTP ; EP%IOR= 2 + EP%JG1=1 ; EP%JG2=1 ; EP%IG1=I ; EP%IG2=ISTP; EP%KG1=J ; EP%KG2=JSTP + CASE (4) ; EP%J1=M%JBAR ; EP%J2=M%JBAR ; EP%I1=I-1 ; EP%I2=ISTP ; EP%K1=J-1 ; EP%K2=JSTP ; EP%IOR=-2 + EP%JG1=EP%J1 ; EP%JG2=EP%J2 ; EP%IG1=I ; EP%IG2=ISTP; EP%KG1=J ; EP%KG2=JSTP + CASE (5) ; EP%K1=0 ; EP%K2=0 ; EP%I1=I-1 ; EP%I2=ISTP ; EP%J1=J-1 ; EP%J2=JSTP ; EP%IOR= 3 + EP%KG1=1 ; EP%KG2=1 ; EP%IG1=I ; EP%IG2=ISTP; EP%JG1=J ; EP%JG2=JSTP + CASE (6) ; EP%K1=M%KBAR ; EP%K2=M%KBAR ; EP%I1=I-1 ; EP%I2=ISTP ; EP%J1=J-1 ; EP%J2=JSTP ; EP%IOR=-3 + EP%KG1=EP%K1 ; EP%KG2=EP%K2 ; EP%IG1=I ; EP%IG2=ISTP; EP%JG1=J ; EP%JG2=JSTP + END SELECT + EP%VENT_INDEX = VENT_INDEX ENDDO ILOOP ENDDO JLOOP @@ -2467,6 +2545,7 @@ END SUBROUTINE RE_ALLOCATE_SEGMENTS END SUBROUTINE WRITE_SMOKEVIEW_FILE + !> \brief Status files are used to indicate if FDS has completed SUBROUTINE WRITE_STATUS_FILES diff --git a/Source/mesh.f90 b/Source/mesh.f90 index 02663d74aeb..1911101e1a2 100644 --- a/Source/mesh.f90 +++ b/Source/mesh.f90 @@ -310,8 +310,9 @@ MODULE MESH_VARIABLES INTEGER :: N_RADF=0 TYPE(RAD_FILE_TYPE), ALLOCATABLE, DIMENSION(:) :: RAD_FILE - INTEGER :: N_PATCH,N_BNDF_POINTS + INTEGER :: N_PATCH,N_BNDF_POINTS,N_EXTERIOR_PATCH TYPE(PATCH_TYPE), ALLOCATABLE, DIMENSION(:) :: PATCH + TYPE(PATCH_TYPE), ALLOCATABLE, DIMENSION(:) :: EXTERIOR_PATCH REAL(EB), ALLOCATABLE, DIMENSION(:,:,:,:) :: UIID INTEGER :: RAD_CALL_COUNTER,ANGLE_INC_COUNTER @@ -454,8 +455,8 @@ MODULE MESH_POINTERS TYPE(SLICE_TYPE), POINTER, DIMENSION(:) :: SLICE INTEGER, POINTER :: N_RADF TYPE(RAD_FILE_TYPE), POINTER, DIMENSION(:) :: RAD_FILE -INTEGER, POINTER :: N_PATCH,N_BNDF_POINTS -TYPE(PATCH_TYPE), POINTER, DIMENSION(:) :: PATCH +INTEGER, POINTER :: N_PATCH,N_BNDF_POINTS,N_EXTERIOR_PATCH +TYPE(PATCH_TYPE), POINTER, DIMENSION(:) :: PATCH,EXTERIOR_PATCH REAL(EB), POINTER, DIMENSION(:,:,:,:) :: UIID INTEGER, POINTER :: RAD_CALL_COUNTER,ANGLE_INC_COUNTER INTEGER, POINTER, DIMENSION(:,:,:) :: INTERPOLATED_MESH @@ -823,8 +824,10 @@ SUBROUTINE POINT_TO_MESH(NM) N_RADF=>M%N_RADF RAD_FILE=>M%RAD_FILE N_PATCH=>M%N_PATCH +N_EXTERIOR_PATCH=>M%N_EXTERIOR_PATCH N_BNDF_POINTS=>M%N_BNDF_POINTS PATCH=>M%PATCH +EXTERIOR_PATCH=>M%EXTERIOR_PATCH UIID=>M%UIID RAD_CALL_COUNTER=>M%RAD_CALL_COUNTER ANGLE_INC_COUNTER=>M%ANGLE_INC_COUNTER diff --git a/Source/type.f90 b/Source/type.f90 index 38e1a4f5dd8..5a471bc65a7 100644 --- a/Source/type.f90 +++ b/Source/type.f90 @@ -1554,7 +1554,7 @@ MODULE TYPES END TYPE RAD_FILE_TYPE TYPE PATCH_TYPE - INTEGER :: I1,I2,J1,J2,K1,K2,IG1,IG2,JG1,JG2,KG1,KG2,IOR,OBST_INDEX + INTEGER :: I1,I2,J1,J2,K1,K2,IG1,IG2,JG1,JG2,KG1,KG2,IOR=0,OBST_INDEX=0,VENT_INDEX=0,MESH_INDEX=0 END TYPE PATCH_TYPE TYPE BOUNDARY_FILE_TYPE