diff --git a/Source/dump.f90 b/Source/dump.f90 index d88f39f4077..7488a531a91 100644 --- a/Source/dump.f90 +++ b/Source/dump.f90 @@ -2349,10 +2349,6 @@ SUBROUTINE WRITE_SMOKEVIEW_FILE ENDIF ENDIF - ! Render GEOM vents using SURF properties (that is, do not draw GEOM vents in Smokeview) - - IF (VT%GEOM) VT%TYPE_INDICATOR = -2 - ENDDO VENT_LOOP ! Look for interpolated mesh boundaries and ensure that Smokeview leaves these blank (VENT_INDICES=-1). diff --git a/Source/func.f90 b/Source/func.f90 index 40119ca8fff..d1a84af43d6 100644 --- a/Source/func.f90 +++ b/Source/func.f90 @@ -3910,7 +3910,7 @@ SUBROUTINE PACK_CFACE(NM,OS,CFA,SURF_INDEX,RC,IC,LC,UNPACK_IT,COUNT_ONLY,CHECK_B ! Assign integer pointers and values IC=IC+1 ; IF (.NOT.COUNT_ONLY) CALL EQUATE(OS%INTEGERS(IC),CFA%SURF_INDEX,UNPACK_IT) -IC=IC+1 ; IF (.NOT.COUNT_ONLY) CALL EQUATE(OS%INTEGERS(IC),CFA%VENT_INDEX,UNPACK_IT) +IC=IC+1 ; IF (.NOT.COUNT_ONLY) CALL EQUATE(OS%INTEGERS(IC),CFA%NODE_INDEX,UNPACK_IT) IC=IC+1 ; IF (.NOT.COUNT_ONLY) CALL EQUATE(OS%INTEGERS(IC),CFA%BOUNDARY_TYPE,UNPACK_IT) IC=IC+1 ; IF (.NOT.COUNT_ONLY) CALL EQUATE(OS%INTEGERS(IC),CFA%CUT_FACE_IND1,UNPACK_IT) IC=IC+1 ; IF (.NOT.COUNT_ONLY) CALL EQUATE(OS%INTEGERS(IC),CFA%CUT_FACE_IND2,UNPACK_IT) diff --git a/Source/geom.f90 b/Source/geom.f90 index dfa92ca358a..79a2b172913 100644 --- a/Source/geom.f90 +++ b/Source/geom.f90 @@ -4121,13 +4121,11 @@ SUBROUTINE GET_EXT_INB_CUTFACES_TO_CFACE ! Local Variables: INTEGER :: ICF, CFACE_INDEX_LOCAL, SURF_INDEX -INTEGER :: IVENT REAL(EB):: ADDMAT(IAXIS:KAXIS,LOW_IND:HIGH_IND) ! GET_CUTCELLS_VERBOSE variables: INTEGER, ALLOCATABLE, DIMENSION(:) :: NCFACE_BY_MESH -TYPE(VENTS_TYPE), POINTER :: VT TYPE(CFACE_TYPE), POINTER :: CFA IF(GET_CUTCELLS_VERBOSE) CALL CPU_TIME(CPUTIME_START) @@ -4310,53 +4308,10 @@ SUBROUTINE GET_EXT_INB_CUTFACES_TO_CFACE MESHES(NM)%N_INTERNAL_CFACE_CELLS = CFACE_INDEX_LOCAL - MESHES(NM)%INTERNAL_CFACE_CELLS_LB ENDDO MESH_LOOP_1 -! Second loop, apply VENTS to change SURF_ID associated with CFACEs: -MESH_LOOP_2 : DO NM=LOWER_MESH_INDEX,UPPER_MESH_INDEX - CALL POINT_TO_MESH(NM) - - ! ! Currently : Modify CFACE SURF_INDEX with VENT information: This needs more development. - IF(TERRAIN_CASE) THEN - VENT_LOOP : DO IVENT=1,MESHES(NM)%N_VENT - VT => VENTS(IVENT) - IF(.NOT.VT%GEOM) CYCLE VENT_LOOP ! Do not apply vent to Geometries. - - ! This test is a simplified test for VENTS changing the CFACE SURF_ID to VENT SURF_ID for all CFACEs whose - ! centroid locations lay within the frame of the IOR grid aligned VENT: - ADDMAT = 0._EB; - SELECT CASE(ABS(VT%IOR)) - CASE(IAXIS) - ADDMAT(IAXIS,LOW_IND) = -(XF_MAX-XS_MIN) ! -DX(VT%I1) Set normal size to 2 times domain size. - ADDMAT(IAXIS,HIGH_IND) = (XF_MAX-XS_MIN) ! DX(VT%I2) XF_MAX, etc. defined in cons.f90. - CASE(JAXIS) - ADDMAT(JAXIS,LOW_IND) = -(YF_MAX-YS_MIN) ! -DY(VT%J1) - ADDMAT(JAXIS,HIGH_IND) = (YF_MAX-YS_MIN) ! DY(VT%J2) - CASE(KAXIS) - ADDMAT(KAXIS,LOW_IND) = -(ZF_MAX-ZS_MIN) ! -DZ(VT%K1) - ADDMAT(KAXIS,HIGH_IND) = (ZF_MAX-ZS_MIN) ! DZ(VT%K2) - CASE DEFAULT - CYCLE VENT_LOOP - END SELECT - ! CFACE Loop to modify SURF_INDEX in INTERNAL_CFACE_CELLS: - CFACE_LOOP_2 : DO CFACE_INDEX_LOCAL=INTERNAL_CFACE_CELLS_LB+1,INTERNAL_CFACE_CELLS_LB+N_INTERNAL_CFACE_CELLS - CFA => CFACE(CFACE_INDEX_LOCAL) - BC => BOUNDARY_COORD(CFA%BC_INDEX) - IF (BC%X < X(VT%I1)+ADDMAT(IAXIS,LOW_IND )) CYCLE CFACE_LOOP_2 - IF (BC%X > X(VT%I2)+ADDMAT(IAXIS,HIGH_IND)) CYCLE CFACE_LOOP_2 - IF (BC%Y < Y(VT%J1)+ADDMAT(JAXIS,LOW_IND )) CYCLE CFACE_LOOP_2 - IF (BC%Y > Y(VT%J2)+ADDMAT(JAXIS,HIGH_IND)) CYCLE CFACE_LOOP_2 - IF (BC%Z < Z(VT%K1)+ADDMAT(KAXIS,LOW_IND )) CYCLE CFACE_LOOP_2 - IF (BC%Z > Z(VT%K2)+ADDMAT(KAXIS,HIGH_IND)) CYCLE CFACE_LOOP_2 - CFA%VENT_INDEX = IVENT - CFA%SURF_INDEX = VT%SURF_INDEX - ENDDO CFACE_LOOP_2 - ENDDO VENT_LOOP - ENDIF -ENDDO MESH_LOOP_2 ! - At this pont all final values of SURF_INDEX have been given to CFACEs. ! Third loop, 1. Compute final FDS area integrals by SURF_ID and GEOM. -! 2. Compute input areas by SURF_ID and GEOM. First sum over GEOM FACES SURF_IDs, -! then VENTS input surfaces are assigned to corresponding GEOMs and SURF_IDs if present (VENTs take precedence). +! 2. Compute input areas by SURF_ID and GEOM. First sum over GEOM FACES SURF_IDs. IF(N_GEOMETRY>0) THEN ALLOCATE(FDS_AREA_GEOM(0:N_SURF,N_GEOMETRY)); FDS_AREA_GEOM = 0._EB ENDIF @@ -8855,7 +8810,7 @@ SUBROUTINE INIT_CFACE_CELL(NM,ICF,IFACE,CFACE_INDEX,SURF_INDEX,STAGE_FLG,IS_INB, CF=> CUT_FACE(ICF) STAGE_FLG_BRANCH : SELECT CASE(STAGE_FLG) - + CASE(INTEGER_ONE) ! Geometry information for CFACE. CALL ALLOCATE_STORAGE(NM,SURF_INDEX=SURF_INDEX,CFACE_INDEX=CFACE_INDEX) @@ -8865,6 +8820,8 @@ SUBROUTINE INIT_CFACE_CELL(NM,ICF,IFACE,CFACE_INDEX,SURF_INDEX,STAGE_FLG,IS_INB, B1 => M%BOUNDARY_PROP1(CFA%B1_INDEX) CFA%SURF_INDEX = SURF_INDEX + CFA%NODE_INDEX = SURFACE(SURF_INDEX)%NODE_INDEX + B1%NODE_INDEX = CFA%NODE_INDEX BC%X = CF%XYZCEN(IAXIS,IFACE) BC%Y = CF%XYZCEN(JAXIS,IFACE) @@ -8880,7 +8837,6 @@ SUBROUTINE INIT_CFACE_CELL(NM,ICF,IFACE,CFACE_INDEX,SURF_INDEX,STAGE_FLG,IS_INB, IBOD = CF%BODTRI(1,IFACE) IWSEL = CF%BODTRI(2,IFACE) - CFA%VENT_INDEX = GEOMETRY(IBOD)%VENTS(IWSEL) ! Normal to cut-face: V2(IAXIS:KAXIS) = CF%XYZVERT(IAXIS:KAXIS,CF%CFELEM(2,IFACE))-CF%XYZCEN(IAXIS:KAXIS,IFACE) @@ -8921,7 +8877,7 @@ SUBROUTINE INIT_CFACE_CELL(NM,ICF,IFACE,CFACE_INDEX,SURF_INDEX,STAGE_FLG,IS_INB, ! External mesh boundary CFACES inherit the underlaying WALL type. CFA%BOUNDARY_TYPE = WC%BOUNDARY_TYPE - CFA%VENT_INDEX = WC%VENT_INDEX + CFA%NODE_INDEX = BOUNDARY_PROP1(WC%B1_INDEX)%NODE_INDEX BC%II = WC_BC%II BC%JJ = WC_BC%JJ @@ -22174,10 +22130,10 @@ SUBROUTINE READ_GEOM CHARACTER(LABEL_LENGTH) :: ID,MATL_ID,TEXTURE_MAPPING, & DEVC_ID,CTRL_ID,SURF_IDS(3),SURF_ID6(6),MOVE_ID CHARACTER(MESSAGE_LENGTH) :: BUFFER,FN_BINGEOM,BINARY_FILE -CHARACTER(LABEL_LENGTH), ALLOCATABLE, DIMENSION(:) :: SURF_ID,VENT_ID +CHARACTER(LABEL_LENGTH), ALLOCATABLE, DIMENSION(:) :: SURF_ID REAL(EB), ALLOCATABLE, DIMENSION(:) :: ZVALS,TFACES REAL(EB), ALLOCATABLE, TARGET, DIMENSION(:) :: VERTS,VERTS_AUX -INTEGER, ALLOCATABLE, DIMENSION(:) :: SURF_ID_IND,VENT_ID_IND,POLY +INTEGER, ALLOCATABLE, DIMENSION(:) :: SURF_ID_IND,POLY INTEGER, ALLOCATABLE, TARGET, DIMENSION(:) :: FACES,FACES_AUX,VOLUS,OFACES,SURFS,SURFS2 LOGICAL, ALLOCATABLE, DIMENSION(:) :: IS_EXTERNAL @@ -22192,7 +22148,7 @@ SUBROUTINE READ_GEOM GEOM_TYPE,NXB,IJK(3),N_LEVELS,N_LAT,N_LONG,SPHERE_TYPE,BOXVERTLIST(8),NI,NIJ,IVOL,SORT_FACES,II,II1,II2,II3,& X1AXIS,NNN,CYLINDER_NSEG_THETA,CYLINDER_NSEG_AXIS,CYL_FIND(LOW_IND:HIGH_IND,1:3),CELL_BLOCK_IOR -LOGICAL :: HAVE_SURF,HAVE_VENT,HAVE_MATL,IN_LIST,SURF_INDEX_PER_FACE,BNDF_GEOM,LOGTEST +LOGICAL :: HAVE_SURF,HAVE_MATL,IN_LIST,SURF_INDEX_PER_FACE,BNDF_GEOM,LOGTEST REAL(EB), POINTER, DIMENSION(:) :: V1,V2,V3,V4 INTEGER, POINTER, DIMENSION(:) :: FACEI,FACEJ,FACE_FROM,FACE_TO,VOL TYPE(MESH_TYPE), POINTER :: M @@ -22235,7 +22191,7 @@ SUBROUTINE READ_GEOM CYLINDER_RADIUS,CYLINDER_LENGTH,CYLINDER_NSEG_THETA,CYLINDER_NSEG_AXIS,& EXTRUDE,EXTEND_TERRAIN,FACES,ID,IJK,IS_TERRAIN,MOVE_ID,N_LAT,N_LEVELS,N_LONG,POLY,& RGB,SPHERE_ORIGIN,SPHERE_RADIUS,SPHERE_TYPE,SURF_ID,SURF_IDS,SURF_ID6,& - TEXTURE_MAPPING,TEXTURE_ORIGIN,TEXTURE_SCALE,TRANSPARENCY,VENT_ID,& + TEXTURE_MAPPING,TEXTURE_ORIGIN,TEXTURE_SCALE,TRANSPARENCY,& VERTS,XB,ZMIN,ZVALS,ZVAL_HORIZON ! first pass - count number of &GEOM lines. @@ -23326,9 +23282,7 @@ SUBROUTINE READ_GEOM ENDDO ALLOCATE(G%SURF_ID(1:N_SURF_ID)) G%SURF_ID(1:N_SURF_ID) = SURF_ID(1:N_SURF_ID) - ALLOCATE(G%VENT_ID(1:N_SURF_ID)) - G%VENT_ID(1:N_SURF_ID) = VENT_ID(1:N_SURF_ID) - + ! Now find correspondence with SURFACE(N)%ID: IF (ALLOCATED(SURF_ID_IND)) DEALLOCATE(SURF_ID_IND) ALLOCATE(SURF_ID_IND(N_SURF_ID)) @@ -23350,35 +23304,6 @@ SUBROUTINE READ_GEOM ENDIF G%HAVE_SURF = HAVE_SURF - ! Look for non-'null' VENTS: - HAVE_VENT=.FALSE. - DO I = 1, MAX_SURF_IDS - IF (TRIM(VENT_ID(I))=='null') CYCLE - HAVE_VENT=.TRUE. - ENDDO - G%HAVE_VENT = HAVE_VENT - - IF(HAVE_VENT) THEN - ! Build single VENT_ID index list: - IF (ALLOCATED(VENT_ID_IND)) DEALLOCATE(VENT_ID_IND); ALLOCATE(VENT_ID_IND(0:MAX_SURF_IDS)); VENT_ID_IND = 0 - DO I = 1, MAX_SURF_IDS ! Here we run over the GEOM local vent array max range. - IF (TRIM(VENT_ID(I))=='null') CYCLE ! Cycle if undefined vent, its VENT_ID_IND(I)=0. - ! Get VENT Index: - IN_LIST = .FALSE. - DO J = 1, N_VENT - IF (TRIM(VENT_ID(I))/=TRIM(VENTS(J)%ID)) CYCLE - VENT_ID_IND(I)=J - IN_LIST = .TRUE. - EXIT - ENDDO - IF(.NOT.IN_LIST) THEN - WRITE(MESSAGE,'(A,I4,3A)') 'ERROR(735): problem with GEOM, the vent ID(',I,') =',& - TRIM(VENT_ID(I)),' is not defined.' - CALL SHUTDOWN(MESSAGE) - ENDIF - ENDDO - ENDIF - IF (MATL_ID=='null') THEN HAVE_MATL = .FALSE. ENDIF @@ -23671,10 +23596,6 @@ SUBROUTINE READ_GEOM ALLOCATE(G%SURFS(N_FACES),STAT=IZERO) CALL ChkMemErr('READ_GEOM','G%SURFS',IZERO) - ALLOCATE(G%VENTS(N_FACES),STAT=IZERO) - CALL ChkMemErr('READ_GEOM','G%VENTS',IZERO) - G%VENTS = 0 - PER_FACE_IF: IF (SURF_INDEX_PER_FACE) THEN DO I=1,N_FACES IF ( SURFS(I) <= 0 ) THEN @@ -23682,10 +23603,6 @@ SUBROUTINE READ_GEOM ELSE G%SURFS(I) = SURF_ID_IND(SURFS(I)) ENDIF - IF (HAVE_VENT) THEN - G%VENTS(I) = VENT_ID_IND(SURFS(I)) ! Uses SURF index in local numeration from FACES input. - IF(G%VENTS(I)>0) G%SURFS(I) = VENTS(G%VENTS(I))%SURF_INDEX ! Change SURF to apply to the vent surface. - ENDIF ENDDO DEALLOCATE(SURF_ID_IND) ELSE @@ -23712,26 +23629,10 @@ SUBROUTINE READ_GEOM IF (SURF_ID6(4)==SURFACE(NNN)%ID .AND. NVECI(2)> TWO_EPSILON_EB) G%SURFS(I) = NNN ! Y2 IF (SURF_ID6(5)==SURFACE(NNN)%ID .AND. NVECI(3)<-TWO_EPSILON_EB) G%SURFS(I) = NNN ! Z1 IF (SURF_ID6(6)==SURFACE(NNN)%ID .AND. NVECI(3)> TWO_EPSILON_EB) G%SURFS(I) = NNN ! Z2 - IF (HAVE_VENT) THEN - IF (SURF_ID(1)==SURFACE(NNN)%ID .AND. ANY(ABS(NVECI(:))>TWO_EPSILON_EB)) G%VENTS(I)=VENT_ID_IND(1) !all sides - IF (SURF_IDS(2)==SURFACE(NNN)%ID .AND. (ABS(NVECI(1))>TWO_EPSILON_EB .OR. ABS(NVECI(2))>TWO_EPSILON_EB) ) & - G%VENTS(I) = VENT_ID_IND(2) ! sides - IF (SURF_IDS(1)==SURFACE(NNN)%ID .AND. NVECI(3)> TWO_EPSILON_EB) G%VENTS(I) = VENT_ID_IND(1) ! top - IF (SURF_IDS(3)==SURFACE(NNN)%ID .AND. NVECI(3)<-TWO_EPSILON_EB) G%VENTS(I) = VENT_ID_IND(3) ! bottom - IF (SURF_ID6(1)==SURFACE(NNN)%ID .AND. NVECI(1)<-TWO_EPSILON_EB) G%VENTS(I) = VENT_ID_IND(1) ! X1 - IF (SURF_ID6(2)==SURFACE(NNN)%ID .AND. NVECI(1)> TWO_EPSILON_EB) G%VENTS(I) = VENT_ID_IND(2) ! X2 - IF (SURF_ID6(3)==SURFACE(NNN)%ID .AND. NVECI(2)<-TWO_EPSILON_EB) G%VENTS(I) = VENT_ID_IND(3) ! Y1 - IF (SURF_ID6(4)==SURFACE(NNN)%ID .AND. NVECI(2)> TWO_EPSILON_EB) G%VENTS(I) = VENT_ID_IND(4) ! Y2 - IF (SURF_ID6(5)==SURFACE(NNN)%ID .AND. NVECI(3)<-TWO_EPSILON_EB) G%VENTS(I) = VENT_ID_IND(5) ! Z1 - IF (SURF_ID6(6)==SURFACE(NNN)%ID .AND. NVECI(3)> TWO_EPSILON_EB) G%VENTS(I) = VENT_ID_IND(6) ! Z2 - - IF(G%VENTS(I)>0) G%SURFS(I) = VENTS(G%VENTS(I))%SURF_INDEX ! Change SURF to apply to the vent surface. - ENDIF ENDDO SURF_LOOP ENDDO FACE_LOOP ENDIF BOX_TYPE_IF ENDIF PER_FACE_IF - IF(HAVE_VENT) DEALLOCATE(VENT_ID_IND) ! Test for Unsupported surfaces: DO I=1,N_FACES @@ -23813,9 +23714,10 @@ SUBROUTINE READ_GEOM DEALLOCATE(GEOM_LINE) +CC_IBM = .TRUE. + IF( (T_END-T_BEGIN) < TWO_EPSILON_EB) RETURN -CC_IBM = .TRUE. ! If unstructured projection defined set Pressure solver on unstructured grid. IF (PRES_FLAG/=UGLMAT_FLAG) THEN PRES_METHOD = 'ULMAT' @@ -24313,10 +24215,6 @@ SUBROUTINE ALLOCATE_BUFFERS ALLOCATE(SURF_ID(MAX_SURF_IDS+1),STAT=IZERO) CALL ChkMemErr('ALLOCATE_BUFFERS','SURF_ID',IZERO) -IF(ALLOCATED(VENT_ID)) DEALLOCATE(VENT_ID) -ALLOCATE(VENT_ID(MAX_SURF_IDS+1),STAT=IZERO) -CALL ChkMemErr('ALLOCATE_BUFFERS','VENT_ID',IZERO) - IF(ALLOCATED(ZVALS)) DEALLOCATE(ZVALS) ALLOCATE(ZVALS(MAX_ZVALS+1),STAT=IZERO) CALL ChkMemErr('ALLOCATE_BUFFERS','ZVALS',IZERO) @@ -24351,7 +24249,6 @@ SUBROUTINE SET_GEOM_DEFAULTS ZMIN=ZS_MIN WRITE(ID,'(A,I0)') 'geom_',N SURF_ID(:)='null' - VENT_ID(:)='null' SURF_IDS = 'null' SURF_ID6 = 'null' MATL_ID = 'null' diff --git a/Source/hvac.f90 b/Source/hvac.f90 index 88533edebd0..76b0b903a36 100644 --- a/Source/hvac.f90 +++ b/Source/hvac.f90 @@ -118,6 +118,7 @@ SUBROUTINE READ_HVAC LOGICAL :: DAMPER !< Flag indicating that a damper is present in a DUCT. LOGICAL :: REVERSE !< Flag indicating that a specfied flow or FAN in a DUCT is from the second to the first node. LOGICAL :: AMBIENT !< Flag indicating a DUCTNODE is connected to the ambient. +LOGICAL :: GEOM !< Flag indicating a DUCTNODE is connected to GEOM. LOGICAL :: LEAK_ENTHALPY !< Flag indicating that the boundary condition for a LEAKAGE duct should preserve enthalpy. LOGICAL :: INITIALIZED_HVAC_MASS_TRANSPORT !< Flag indicating DUCTs with N_CELLS>1 have been initiazed. LOGICAL :: DUCT_QUANTITY_DEFINED=.FALSE. !< Flag indicating a DUCT_QUANTITY list has alreayd been defined @@ -144,7 +145,7 @@ SUBROUTINE READ_HVAC TYPE(HVAC_QUANTITY_TYPE), POINTER :: HQT !< Pointer to a DUCT_ or NODE_QUANTITY_ARRAY NAMELIST /HVAC/ AIRCOIL_ID,AMBIENT,AREA,CLEAN_LOSS,COOLANT_SPECIFIC_HEAT,COOLANT_MASS_FLOW,COOLANT_TEMPERATURE,CTRL_ID,& DAMPER,DEBUG,DEVC_ID,DIAMETER,DISCHARGE_COEFFICIENT,DUCT_ID,& - EFFICIENCY,FAN_ID,FILTER_ID,FIXED_Q,ID,LEAK_ENTHALPY,LEAK_PRESSURE_EXPONENT,LEAK_REFERENCE_PRESSURE,& + EFFICIENCY,FAN_ID,FILTER_ID,FIXED_Q,GEOM,ID,LEAK_ENTHALPY,LEAK_PRESSURE_EXPONENT,LEAK_REFERENCE_PRESSURE,& LENGTH,LOADING,LOADING_MULTIPLIER,LOSS,& MASS_FLOW,MAX_FLOW,MAX_PRESSURE,N_CELLS,NETWORK_ID,NODE_ID,PERIMETER,QUANTITY,QUANTITY_SPEC_ID,& RAMP_ID,RAMP_LOSS,REVERSE,ROUGHNESS,ROUND,SPEC_ID,SQUARE,TAU_AC,TAU_FAN,TAU_VF,TRANSPORT_PARTICLES,& @@ -428,18 +429,24 @@ SUBROUTINE READ_HVAC CALL SHUTDOWN(MESSAGE); RETURN ENDIF DN%VENT_ID = VENT_ID + DN%GEOM = GEOM + IF (DN%VENT .AND. DN%GEOM) THEN + WRITE(MESSAGE,'(A,A,A,A)') 'ERROR(yyy): Problem with ductnode:',TRIM(DN%ID), & + ', cannot assign to both VENT and GEOM.' + CALL SHUTDOWN(MESSAGE); RETURN + ENDIF DN%READ_IN = .TRUE. IF (TRIM(VENT_ID)/='null') DN%VENT=.TRUE. ! Set temporary node elevation for vents so WIND can establish T and P RAMPs - IF (DN%VENT .AND. XYZ(3) <-1.E9) XYZ(3) = ZS_MIN - IF (.NOT. DN%VENT .AND. XYZ(3)<-1.E9) THEN + IF ((DN%VENT .OR. DN%GEOM).AND. XYZ(3) <-1.E9) XYZ(3) = ZS_MIN + IF (.NOT. (DN%VENT .OR. DN%GEOM) .AND. XYZ(3)<-1.E9) THEN WRITE(MESSAGE,'(A,A,A,I5)') 'ERROR(514): Ambient or internal ductnode requires an elevation, XYZ(3). Ductnode ID:',& TRIM(DN%ID),', HVAC line number:',NN CALL SHUTDOWN(MESSAGE); RETURN ENDIF DN%XYZ = XYZ - IF (ALL(DN%XYZ>-1.E9) .OR. DN%VENT) DN%SPECIFIED_XYZ = .TRUE. - IF (.NOT. DN%VENT) THEN + IF (ALL(DN%XYZ>-1.E9) .OR. DN%VENT .OR. DN%GEOM) DN%SPECIFIED_XYZ = .TRUE. + IF (.NOT. (DN%VENT .OR. DN%GEOM)) THEN IF (DN%XYZ(1) <=-1.E9_EB) DN%XYZ(1) = XS_MIN IF (DN%XYZ(2) <=-1.E9_EB) DN%XYZ(2) = YS_MIN ENDIF @@ -448,13 +455,13 @@ SUBROUTINE READ_HVAC IF (NODE_DUCT_A(I_DUCTNODE,ND) == 'null') EXIT DN%N_DUCTS=ND ENDDO - IF (DN%N_DUCTS == 1 .AND. .NOT. AMBIENT .AND. VENT_ID=='null') THEN + IF (DN%N_DUCTS == 1 .AND. .NOT. GEOM .AND. .NOT. AMBIENT .AND. VENT_ID=='null') THEN WRITE(MESSAGE,'(A,A,A,I5)') 'ERROR(515): Non-AMBIENT or non VENT-connected ductnode must have >=2 ducts. Ductnode ID:',& TRIM(DN%ID),', HVAC line number:',NN CALL SHUTDOWN(MESSAGE); RETURN ENDIF - IF (DN%N_DUCTS >= 2 .AND. (AMBIENT .OR. VENT_ID/='null')) THEN - WRITE(MESSAGE,'(A,A,A,I5)') 'ERROR(516): AMBIENT or VENT-connected ductnode must have 1 duct. Ductnode ID:',& + IF (DN%N_DUCTS >= 2 .AND. (AMBIENT .OR. GEOM .OR. VENT_ID/='null')) THEN + WRITE(MESSAGE,'(A,A,A,I5)') 'ERROR(516): AMBIENT, GEOM, or VENT-connected ductnode must have 1 duct. Ductnode ID:',& TRIM(DN%ID),', HVAC line number:',NN CALL SHUTDOWN(MESSAGE); RETURN ENDIF @@ -741,6 +748,7 @@ SUBROUTINE SET_HVAC_DEFAULTS FAN_ID = 'null' FIXED_Q = -1.E10_EB FILTER_ID = 'null' +GEOM = .FALSE. LEAK_ENTHALPY = .FALSE. LEAK_PRESSURE_EXPONENT = 0.5_EB LEAK_REFERENCE_PRESSURE = 4._EB @@ -789,15 +797,17 @@ SUBROUTINE PROC_HVAC USE PHYSICAL_FUNCTIONS, ONLY: GET_ENTHALPY USE MPI_F08 -INTEGER :: N,ND,ND2,NM,NN,NF,NV,IERR +INTEGER :: N,ND,ND2,NM,NN,NF,NV,IERR,NG,FI(3) REAL(EB) :: TNOW !< Current CPU time (s) used in computing length of time spent in HVAC routines. REAL(EB) :: ZZ_GET(1:N_TRACKED_SPECIES) !< Species mass fraction array +REAL(EB) :: CF_AREA(N_DUCTNODES),CF_X(N_DUCTNODES),CF_Y(N_DUCTNODES),CF_Z(N_DUCTNODES),AREA,X,Y,Z,XYZ_F(3,3) LOGICAL :: FOUND !< Flag indicating search loop has found the HVAC component assocaited with an ID LOGICAL :: DUMMY = .FALSE. !< Dummy flag TYPE (LAGRANGIAN_PARTICLE_CLASS_TYPE),DIMENSION(:), POINTER:: TEMPALLOC TYPE(DUCTNODE_TYPE), POINTER :: DN TYPE(DUCT_TYPE), POINTER :: DU TYPE(SURFACE_TYPE), POINTER :: SF +TYPE(GEOMETRY_TYPE), POINTER :: G TNOW=CURRENT_TIME() @@ -956,8 +966,6 @@ SUBROUTINE PROC_HVAC ! If the duct node has a VENT associated with it, find it IF (DN%VENT_ID /= 'null') THEN - ALLOCATE(DN%IN_MESH(NMESHES)) - DN%IN_MESH=.FALSE. FOUND = .FALSE. MESH_LOOP: DO NM = 1, NMESHES IF (PROCESS(NM)/=MY_RANK) CYCLE MESH_LOOP ! Only search meshes controlled by the current MPI process @@ -1000,7 +1008,6 @@ SUBROUTINE PROC_HVAC CALL SHUTDOWN(MESSAGE,PROCESS_0_ONLY=.FALSE.) ENDIF ENDIF - DN%IN_MESH(NM) = .TRUE. MESHES(NM)%VENTS(NV)%NODE_INDEX=NN ! Sets node to VENT center based on XB. This value will be used for Smokeview visualization. These values ! will be modified as needed during the run to reflect the actual area of the VENT that is visible. @@ -1010,10 +1017,11 @@ SUBROUTINE PROC_HVAC EXIT NODE_VENT_LOOP ENDIF ENDDO NODE_VENT_LOOP + IF (.NOT. FOUND) DN%XYZ = -1.E11_EB ENDDO MESH_LOOP - - ! Check if any MPI process has FOUND the VENT + + ! Check if any MPI process has FOUND the VENT IF (N_MPI_PROCESSES>1) CALL MPI_ALLREDUCE(MPI_IN_PLACE,STOP_STATUS,INTEGER_ONE,MPI_INTEGER,MPI_MAX,MPI_COMM_WORLD,IERR) @@ -1029,21 +1037,65 @@ SUBROUTINE PROC_HVAC CALL MPI_ALLREDUCE(MPI_IN_PLACE,DN%XYZ(3),INTEGER_ONE,MPI_DOUBLE_PRECISION,MPI_MAX,MPI_COMM_WORLD,IERR) ENDIF - IF (DN%VENT .AND. DN%AMBIENT) THEN - WRITE(MESSAGE,'(A,I5,A,A)') 'ERROR(546): DuctnodeE cannot be AMBIENT and have an assigned VENT_ID. Ductnode:',NN,& +ENDDO NODE_LOOP + +GEOM_IF: IF (CC_IBM .AND. ANY(SURFACE%NODE_INDEX>0)) THEN + CF_AREA = 0._EB + CF_X = 0._EB + CF_Y = 0._EB + CF_Z = 0._EB + NODE_GEOM_LOOP: DO NG=1,N_GEOMETRY + G=>GEOMETRY(NG) + FACES_LOOP: DO NF=1,G%N_FACES + SF=>SURFACE(G%SURFS(NF)) + IF (SF%NODE_INDEX==0) CYCLE FACES_LOOP + FI(1:3) = G%FACES((NF-1)*3+1:(NF-1)*3+3) + XYZ_F(1,1:3) = G%VERTS((FI(1)-1)*3+1:(FI(1)-1)*3+3) + XYZ_F(2,1:3) = G%VERTS((FI(2)-1)*3+1:(FI(2)-1)*3+3) + XYZ_F(3,1:3) = G%VERTS((FI(3)-1)*3+1:(FI(3)-1)*3+3) + AREA = SQRT(((XYZ_F(2,2)-XYZ_F(1,2))*(XYZ_F(3,3)-XYZ_F(1,3))-(XYZ_F(2,3)-XYZ_F(1,3))*(XYZ_F(3,2)-XYZ_F(1,2)))**2 + & + ((XYZ_F(2,3)-XYZ_F(1,3))*(XYZ_F(3,1)-XYZ_F(1,1))-(XYZ_F(2,1)-XYZ_F(1,1))*(XYZ_F(3,3)-XYZ_F(1,3)))**2 + & + ((XYZ_F(2,1)-XYZ_F(1,1))*(XYZ_F(3,2)-XYZ_F(3,1))-(XYZ_F(2,2)-XYZ_F(1,2))*(XYZ_F(3,1)-XYZ_F(1,1)))**2) * 0.5_EB + X = SUM(XYZ_F(:,1))*ONTH + Y = SUM(XYZ_F(:,2))*ONTH + Z = SUM(XYZ_F(:,3))*ONTH + CF_AREA(SF%NODE_INDEX) = CF_AREA(SF%NODE_INDEX) + AREA + CF_X(SF%NODE_INDEX) = CF_X(SF%NODE_INDEX) + X*AREA + CF_Y(SF%NODE_INDEX) = CF_Y(SF%NODE_INDEX) + Y*AREA + CF_Z(SF%NODE_INDEX) = CF_Z(SF%NODE_INDEX) + Z*AREA + ENDDO FACES_LOOP + ENDDO NODE_GEOM_LOOP +ENDIF GEOM_IF + +NODE_LOOP_2: DO NN=1,N_DUCTNODES + DN=> DUCTNODE(NN) + IF (DN%N_DUCTS==1 .AND. .NOT. (DN%VENT .OR. DN%AMBIENT .OR. DN%GEOM) ) THEN + WRITE(MESSAGE,'(A,I5,A,A)') 'ERROR(547): Internal ductnode must have at least two attached ducts. Ductnode:',NN,& ', Ductnode ID:',TRIM(DN%ID) CALL SHUTDOWN(MESSAGE); RETURN ENDIF - IF (DN%N_DUCTS == 1 .AND. .NOT. DN%VENT .AND. .NOT. DN%AMBIENT) THEN - WRITE(MESSAGE,'(A,I5,A,A)') 'ERROR(547): Internal ductnode must have at least two attached ducts. Ductnode:',NN,& + IF (DN%N_DUCTS> 1 .AND. (DN%AMBIENT .OR. DN%VENT .OR. DN%GEOM) ) THEN + WRITE(MESSAGE,'(A,I5,A,A)') 'ERROR(548): External ductnode can only have one attached duct. Ductnode:',NN,& ', Ductnode ID:',TRIM(DN%ID) CALL SHUTDOWN(MESSAGE); RETURN ENDIF - IF (DN%N_DUCTS> 1 .AND. (DN%AMBIENT .OR. DN%VENT) ) THEN - WRITE(MESSAGE,'(A,I5,A,A)') 'ERROR(548): External ductnode can only have one attached duct. Ductnode:',NN,& + IF ((DN%VENT .OR. DN%GEOM) .AND. DN%AMBIENT) THEN + WRITE(MESSAGE,'(A,I5,A,A)') 'ERROR(546): Ductnode cannot be AMBIENT and have an assigned VENT_ID or GEOM. Ductnode:',NN,& ', Ductnode ID:',TRIM(DN%ID) CALL SHUTDOWN(MESSAGE); RETURN ENDIF + + IF (DN%GEOM) THEN + IF (CF_AREA(NN) < TWO_EPSILON_EB) THEN + WRITE(MESSAGE,'(A,I5,A,A,A)') 'ERROR(yyy): Ductnode:',NN,', Ductnode ID:',TRIM(DN%ID),& + ' defined with GEOM had no CFACE found.' + CALL SHUTDOWN(MESSAGE); RETURN + ENDIF + DN%XYZ(1) = CF_X(NN)/CF_AREA(NN) + DN%XYZ(2) = CF_Y(NN)/CF_AREA(NN) + DN%XYZ(3) = CF_Z(NN)/CF_AREA(NN) + ENDIF + ALLOCATE(DN%DUCT_INDEX(DN%N_DUCTS)) ALLOCATE(DN%DIR(DN%N_DUCTS)) DN%DUCT_INDEX = -1 @@ -1091,7 +1143,7 @@ SUBROUTINE PROC_HVAC DN%FILTER_LOADING(1:N_TRACKED_SPECIES,3) = FILTER(DN%FILTER_INDEX)%INITIAL_LOADING(1:N_TRACKED_SPECIES) ENDIF -ENDDO NODE_LOOP +ENDDO NODE_LOOP_2 !Temp arrays for input processing IF (ALLOCATED(DUCT_NODE_A)) DEALLOCATE(DUCT_NODE_A) @@ -1235,7 +1287,7 @@ SUBROUTINE INIT_DUCT_NODE DN%RHO = RHOA ENDIF DN%P_OLD = DN%P - IF (DN%VENT) DN%P = -1.E10_EB + IF (DN%VENT .OR. DN%GEOM) DN%P = -1.E10_EB ZZ_GET(1:N_TRACKED_SPECIES) = DN%ZZ_V(1:N_TRACKED_SPECIES) CALL GET_ENTHALPY(ZZ_GET,DN%CP,DN%TMP) DN%CP = DN%CP / DN%TMP @@ -1447,7 +1499,7 @@ SUBROUTINE MATRIX_SOLVE(NNE) ENDDO DO NN = 1,NE%N_DUCTNODES DN=>DUCTNODE(NE%NODE_INDEX(NN)) - IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) CYCLE + IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) CYCLE DN%P = RHS(NE%MATRIX_INDEX(NE%N_DUCTS+NN)) ENDDO @@ -1510,7 +1562,7 @@ SUBROUTINE HVAC_UPDATE(NNE,DT) N_UPDATED = .FALSE. DO NN = 1,DR%N_DUCTNODES DN=>DUCTNODE(DR%NODE_INDEX(NN)) - IF ((DN%VENT .OR. DN%AMBIENT) .AND. & + IF ((DN%VENT .OR. DN%AMBIENT .OR. DN%GEOM) .AND. & DN%DIR(1)*DUCT(DN%DUCT_INDEX(1))%VEL(NEW) <= 0._EB) N_UPDATED(DR%NODE_INDEX(NN)) = .TRUE. IF (DN%N_DUCTS==2) THEN IF (ABS(DUCT(DN%DUCT_INDEX(1))%VEL(NEW)) < TWO_EPSILON_EB .AND. & @@ -1642,7 +1694,7 @@ SUBROUTINE HVAC_UPDATE(NNE,DT) ENDIF ENDDO DUCT_NODE_LOOP_1 - IF (DN%VENT) THEN + IF (DN%VENT .OR. DN%GEOM) THEN DN%E_SUM = DN%E_SUM + ETOT*DT_MT DN%ZZ_SUM = DN%ZZ_SUM + ZZTOT*DT_MT ENDIF @@ -1669,7 +1721,7 @@ SUBROUTINE HVAC_UPDATE(NNE,DT) DO NN = 1,DR%N_DUCTNODES DN=>DUCTNODE(DR%NODE_INDEX(NN)) - IF (.NOT. DN%VENT) CYCLE + IF (.NOT. (DN%VENT .OR. DN%GEOM)) CYCLE DU => DUCT(DN%DUCT_INDEX(1)) IF (DN%DIR(1)*DU%VEL(NEW) <= 0._EB) CYCLE MTOT = ABS(DU%VEL(NEW))*DU%AREA*DU%RHO_D*DT @@ -1696,7 +1748,7 @@ SUBROUTINE HVAC_UPDATE(NNE,DT) CYCLE ENDIF ENDIF - IF ((DN%LEAKAGE .OR. DN%VENT .OR. DN%AMBIENT) .AND. & + IF ((DN%LEAKAGE .OR. DN%VENT .OR. DN%AMBIENT .OR. DN%GEOM) .AND. & DN%DIR(1)*DUCT(DN%DUCT_INDEX(1))%VEL(NEW) <= 0._EB) N_UPDATED(NE%NODE_INDEX(NN)) = .TRUE. IF (DN%N_DUCTS==2) THEN IF (ABS(DUCT(DN%DUCT_INDEX(1))%VEL(NEW)) < TWO_EPSILON_EB .AND. & @@ -1808,7 +1860,7 @@ SUBROUTINE RHSNODE(NETWORK_INDEX) NE => NETWORK(NETWORK_INDEX) DO NN = 1, NE%N_DUCTNODES DN => DUCTNODE(NE%NODE_INDEX(NN)) - IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) CYCLE + IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) CYCLE ARRAYLOC = NE%MATRIX_INDEX(NE%N_DUCTS+DUCTNODE_NE(NE%NODE_INDEX(NN))) DO ND = 1,DN%N_DUCTS DU => DUCT(DN%DUCT_INDEX(ND)) @@ -1835,7 +1887,7 @@ SUBROUTINE LHSNODE(NETWORK_INDEX) NE => NETWORK(NETWORK_INDEX) DO NN = 1, NE%N_DUCTNODES DN => DUCTNODE(NE%NODE_INDEX(NN)) - IF (DN%VENT .OR. DN%LEAKAGE .OR. DN%AMBIENT) CYCLE + IF (DN%VENT .OR. DN%LEAKAGE .OR. DN%AMBIENT .OR. DN%GEOM) CYCLE ARRAYLOC1 = NE%MATRIX_INDEX(NE%N_DUCTS+DUCTNODE_NE(NE%NODE_INDEX(NN))) DO ND = 1,DN%N_DUCTS DU => DUCT(DN%DUCT_INDEX(ND)) @@ -1918,9 +1970,9 @@ SUBROUTINE RHSDUCT(NETWORK_INDEX) DN=>DUCTNODE(DU%NODE_INDEX(1)) IF (DN%AMBIENT) THEN HEAD = HEAD + DN%P - ELSEIF (DN%VENT .OR. DN%LEAKAGE) THEN + ELSEIF (DN%VENT .OR. DN%LEAKAGE .OR. DN%GEOM) THEN HEAD = HEAD + DN%P - IF (DN%VENT .AND. HVAC_LOCAL_PRESSURE) & + IF ((DN%VENT .OR. DN%GEOM) .AND. HVAC_LOCAL_PRESSURE) & HEAD = HEAD - DN%DIR(1) * DU%RHO_D * DU%VEL(OLD) * DU%AREA / NODE_AREA_EX(DU%NODE_INDEX(1)) / (GAMMA * DT_HV) IF (N_ZONE > 0) THEN IPZ = DN%ZONE_INDEX @@ -1931,9 +1983,9 @@ SUBROUTINE RHSDUCT(NETWORK_INDEX) DN=>DUCTNODE(DU%NODE_INDEX(2)) IF (DN%AMBIENT) THEN HEAD = HEAD - DN%P - ELSEIF (DN%VENT .OR. DN%LEAKAGE) THEN + ELSEIF (DN%VENT .OR. DN%LEAKAGE .OR. DN%GEOM) THEN HEAD = HEAD - DN%P - IF (DN%VENT .AND. HVAC_LOCAL_PRESSURE) & + IF ((DN%VENT .OR. DN%GEOM) .AND. HVAC_LOCAL_PRESSURE) & HEAD = HEAD + DN%DIR(1) * DU%RHO_D * DU%VEL(OLD) * DU%AREA / NODE_AREA_EX(DU%NODE_INDEX(2)) / (GAMMA * DT_HV) IF (N_ZONE > 0) THEN IPZ = DN%ZONE_INDEX @@ -1978,7 +2030,7 @@ SUBROUTINE LHSDUCT(NETWORK_INDEX) ARRAYLOC1 = NE%MATRIX_INDEX(DUCT_NE(NE%DUCT_INDEX(ND))) LHS(ARRAYLOC1,ARRAYLOC1) = 1._EB+0.5_EB*DT_HV*DU%TOTAL_LOSS/DU%LENGTH*ABS(DU%VEL(PREVIOUS)+DU%VEL(GUESS)) DN=>DUCTNODE(DU%NODE_INDEX(1)) - IF (.NOT. DN%VENT) THEN + IF (.NOT. (DN%VENT .OR. DN%GEOM)) THEN IF (.NOT. DN%AMBIENT .AND. .NOT. DN%LEAKAGE) THEN ARRAYLOC2 = NE%MATRIX_INDEX(NE%N_DUCTS+DUCTNODE_NE(DU%NODE_INDEX(1))) LHS(ARRAYLOC1,ARRAYLOC2) = -DT_HV/(DU%RHO_D*DU%LENGTH) @@ -2012,7 +2064,7 @@ SUBROUTINE LHSDUCT(NETWORK_INDEX) ENDIF ENDIF DN=>DUCTNODE(DU%NODE_INDEX(2)) - IF (.NOT. DN%VENT) THEN + IF (.NOT. (DN%VENT .OR. DN%GEOM)) THEN IF (.NOT. DN%AMBIENT .AND. .NOT. DN%LEAKAGE) THEN ARRAYLOC2 = NE%MATRIX_INDEX(NE%N_DUCTS+DUCTNODE_NE(DU%NODE_INDEX(2))) LHS(ARRAYLOC1,ARRAYLOC2) = DT_HV/(DU%RHO_D*DU%LENGTH) @@ -2222,13 +2274,13 @@ SUBROUTINE HVAC_BC_IN(NM) ENDDO WALL_LOOP WALL_FLAG = .FALSE. + CFACE_LOOP: DO ICF=INTERNAL_CFACE_CELLS_LB+1,INTERNAL_CFACE_CELLS_LB+N_INTERNAL_CFACE_CELLS CFA => CFACE(ICF) B1 => BOUNDARY_PROP1(CFA%B1_INDEX) BC => BOUNDARY_COORD(CFA%BC_INDEX) SF => SURFACE(CFA%SURF_INDEX) NODE_INDEX => B1%NODE_INDEX - VENT_INDEX => CFA%VENT_INDEX ! Reset indices to zero in case of adding an OSBT NODE_INDEX = 0 CALL INITIALIZE_HVAC @@ -2247,11 +2299,11 @@ SUBROUTINE INITIALIZE_HVAC ZONE_LEAK_IF: IF (ALL(SF%LEAK_PATH < 0)) THEN - IF (VENT_INDEX == 0) RETURN - IF (VENTS(VENT_INDEX)%NODE_INDEX < 0) RETURN - NODE_INDEX = VENTS(VENT_INDEX)%NODE_INDEX IF (WALL_FLAG) THEN + IF (VENT_INDEX == 0) RETURN + IF (VENTS(VENT_INDEX)%NODE_INDEX < 0) RETURN + NODE_INDEX = VENTS(VENT_INDEX)%NODE_INDEX IF (WC%OBST_INDEX > 0) THEN IF (OBSTRUCTION(WC%OBST_INDEX)%REMOVABLE) THEN ERROR_FLAG = .TRUE. @@ -2260,6 +2312,9 @@ SUBROUTINE INITIALIZE_HVAC CALL SHUTDOWN(MESSAGE,PROCESS_0_ONLY=.FALSE.); RETURN ENDIF ENDIF + ELSE + NODE_INDEX = CFA%NODE_INDEX + IF (NODE_INDEX<=0) RETURN ENDIF IOR = BC%IOR @@ -2497,7 +2552,7 @@ SUBROUTINE DETERMINE_FIXED_ELEMENTS(T,CHANGE) NODE_LOOP: DO NN = 1, N_DUCTNODES DN=>DUCTNODE(NN) - IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) CYCLE NODE_LOOP + IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) CYCLE NODE_LOOP COUNTER = 0 VOLUME_FLOW = 0._EB ZERO_AREA = .FALSE. @@ -2682,7 +2737,7 @@ SUBROUTINE SETUP_SOLUTION_POINTERS ENDDO DO NN=1,NE%N_DUCTNODES DN=>DUCTNODE(NE%NODE_INDEX(NN)) - IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) CYCLE + IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) CYCLE COUNTER = COUNTER + 1 NE%MATRIX_INDEX(NE%N_DUCTS+NN)=COUNTER ENDDO @@ -2736,7 +2791,7 @@ SUBROUTINE UPDATE_LOSS(T,DT,NNE) ENDIF ENDIF - NODECLASS: IF (DN%VENT .OR. DN%AMBIENT) THEN + NODECLASS: IF (DN%VENT .OR. DN%AMBIENT .OR. DN%GEOM) THEN ! If node is an external node loss is simply based on inflow or outflow or half loss if no flow IF (DUCT(DN%DUCT_INDEX(1))%AREA < TWO_EPSILON_EB .OR. DUCT(DN%DUCT_INDEX(1))%LOCALIZED_LEAKAGE) CYCLE IF(DUCT(DN%DUCT_INDEX(1))%VEL(PREVIOUS)*DN%DIR(1) > 1.E-6_EB) THEN @@ -2900,7 +2955,7 @@ SUBROUTINE SET_DONOR(NNE) NODELOOP: DO NN=1,NE%N_DUCTNODES DN=>DUCTNODE(NE%NODE_INDEX(NN)) - IF(DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) THEN + IF(DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) THEN DN%RHO= DN%RHO_V DN%TMP= DN%TMP_V DN%ZZ = DN%ZZ_V @@ -2980,7 +3035,7 @@ SUBROUTINE CONVERGENCE_CHECK(NNE) ! Check node mass conservation convergence DO NN=1,NE%N_DUCTNODES DN => DUCTNODE(NE%NODE_INDEX(NN)) - IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) CYCLE + IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) CYCLE MSUM = 0._EB MTOT = 0._EB COUNT = 0 @@ -3028,7 +3083,7 @@ SUBROUTINE COLLAPSE_HVAC_BC(T) IF (CONNECTED_ZONES(0,DN%ZONE_INDEX)>0) DN%ZONE_INDEX = 0 ENDIF - INTERNAL_NODE_IF: IF (((DN%VENT .OR. DN%LEAKAGE) .AND. .NOT. DN%AMBIENT) .OR. & + INTERNAL_NODE_IF: IF (((DN%VENT .OR. DN%LEAKAGE .OR. DN%GEOM) .AND. .NOT. DN%AMBIENT) .OR. & (DN%AMBIENT .AND. NODE_AREA(NN) > 0._EB)) THEN ZZ_GET = 0._EB AREA = NODE_AREA(NN) @@ -3141,7 +3196,7 @@ SUBROUTINE SET_INIT_HVAC DO NN=1,N_DUCTNODES DN=>DUCTNODE(NN) - IF (.NOT. DN%VENT .AND. .NOT. DN%LEAKAGE) CYCLE + IF (.NOT. (DN%VENT .OR. DN%LEAKAGE .OR. DN%GEOM)) CYCLE DN%CP = DN%CP_V DN%TMP = DN%TMP_V DN%RHO = DN%RHO_V @@ -4362,12 +4417,12 @@ SUBROUTINE RHSDUCT_QFAN(DUCTRUN_INDEX,NF,T) RGZ = 0._EB DN=>DUCTNODE(DU%NODE_INDEX(1)) IF (DN%DUCTRUN_M_INDEX <=0) HEAD = DN%P - IF (DN%VENT .AND. HVAC_LOCAL_PRESSURE) & + IF ((DN%VENT .OR. DN%GEOM) .AND. HVAC_LOCAL_PRESSURE) & HEAD = HEAD - DN%DIR(1) * DR%RHO_D(ND,NF) * DU%VEL(OLD) * DU%AREA / NODE_AREA_EX(DU%NODE_INDEX(1)) / (GAMMA * DT_QF) XYZ = DN%XYZ DN=>DUCTNODE(DU%NODE_INDEX(2)) IF (DN%DUCTRUN_M_INDEX <=0) HEAD = HEAD - DN%P - IF (DN%VENT .AND. HVAC_LOCAL_PRESSURE) & + IF ((DN%VENT .OR. DN%GEOM) .AND. HVAC_LOCAL_PRESSURE) & HEAD = HEAD + DN%DIR(1) * DR%RHO_D(ND,NF) * DU%VEL(OLD) * DU%AREA / NODE_AREA_EX(DU%NODE_INDEX(2)) / (GAMMA * DT_QF) XYZ = DN%XYZ - XYZ IF (.NOT. DU%LEAKAGE) THEN @@ -4414,10 +4469,12 @@ SUBROUTINE LHSDUCT_QFAN(DUCTRUN_INDEX,NF) LHS(ND,ND) = 1._EB+0.5_EB*DT_QF*DR%LOSS(ND,NF)/DU%LENGTH*ABS(DR%VEL(ND,NF,PREVIOUS)+DR%VEL(ND,NF,GUESS)) DN=>DUCTNODE(DU%NODE_INDEX(1)) IF (DN%DUCTRUN_M_INDEX > 0) LHS(ND,DR%N_M_DUCTS + DN%DUCTRUN_M_INDEX) = -DT_QF/(DR%RHO_D(ND,NF)*DU%LENGTH) - IF (DN%VENT .AND. HVAC_LOCAL_PRESSURE) LHS(ND,ND) = LHS(ND,ND)-DN%DIR(1)*DU%AREA/(DU%LENGTH*GAMMA*NODE_AREA_EX(DU%NODE_INDEX(1))) + IF ((DN%VENT .OR. DN%GEOM) .AND. HVAC_LOCAL_PRESSURE) & + LHS(ND,ND) = LHS(ND,ND)-DN%DIR(1)*DU%AREA/(DU%LENGTH*GAMMA*NODE_AREA_EX(DU%NODE_INDEX(1))) DN=>DUCTNODE(DU%NODE_INDEX(2)) IF (DN%DUCTRUN_M_INDEX > 0) LHS(ND,DR%N_M_DUCTS + DN%DUCTRUN_M_INDEX) = DT_QF/(DR%RHO_D(ND,NF)*DU%LENGTH) - IF (DN%VENT .AND. HVAC_LOCAL_PRESSURE) LHS(ND,ND) = LHS(ND,ND)+DN%DIR(1)*DU%AREA/(DU%LENGTH*GAMMA*NODE_AREA_EX(DU%NODE_INDEX(2))) + IF ((DN%VENT .OR. DN%GEOM) .AND. HVAC_LOCAL_PRESSURE) & + LHS(ND,ND) = LHS(ND,ND)+DN%DIR(1)*DU%AREA/(DU%LENGTH*GAMMA*NODE_AREA_EX(DU%NODE_INDEX(2))) ENDDO DUCT_LOOP END SUBROUTINE LHSDUCT_QFAN @@ -4471,7 +4528,7 @@ SUBROUTINE CONVERGENCE_CHECK_QFAN(DUCTRUN_INDEX,NF) ! Check node mass conservation convergence DO NN=1,DR%N_M_DUCTNODES DN => DUCTNODE(DR%NODE_INDEX(NN)) - IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) CYCLE + IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) CYCLE MSUM = 0._EB MTOT = 0._EB COUNT = 0 @@ -4591,7 +4648,7 @@ SUBROUTINE UPDATE_LOSS_QFAN(T,DUCTRUN_INDEX,NF) ENDIF ENDIF - NODECLASS: IF(DN%VENT .OR. DN%AMBIENT) THEN + NODECLASS: IF(DN%VENT .OR. DN%AMBIENT .OR. DN%GEOM) THEN ! If node is an external node loss is simply based on inflow or outflow or half loss if no flow IF (DUCT(DN%DUCT_INDEX(1))%AREA < TWO_EPSILON_EB .OR. DUCT(DN%DUCT_INDEX(1))%LOCALIZED_LEAKAGE) CYCLE D_INDEX = DUCT(DN%DUCT_INDEX(1))%DUCTRUN_INDEX @@ -4750,7 +4807,7 @@ SUBROUTINE SET_DONOR_QFAN(DUCTRUN_INDEX,NF) ENDIF DN=>DUCTNODE(NN) - IF(DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) THEN + IF(DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) THEN DR%RHO_D(ND,NF) = DN%RHO_V DR%TMP_D(ND,NF) = DN%TMP_V DR%CP_D(ND,NF) = DN%CP_V @@ -4763,7 +4820,7 @@ SUBROUTINE SET_DONOR_QFAN(DUCTRUN_INDEX,NF) ENDIF ELSE DN=>DUCTNODE(DU%NODE_INDEX(1)) - IF(DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) THEN + IF(DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) THEN DR%RHO_D(ND,NF) = 0.5_EB*DN%RHO_V DR%TMP_D(ND,NF) = 0.5_EB*DN%TMP_V DR%CP_D(ND,NF) = 0.5_EB*DN%CP_V @@ -4775,7 +4832,7 @@ SUBROUTINE SET_DONOR_QFAN(DUCTRUN_INDEX,NF) DR%ZZ_D(ND,NF,:) = 0.5_EB*DR%ZZ_N(DN%DUCTRUN_INDEX,NF,:) ENDIF DN=>DUCTNODE(DU%NODE_INDEX(2)) - IF(DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) THEN + IF(DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) THEN DR%RHO_D(ND,NF) = DR%RHO_D(ND,NF) + 0.5_EB*DN%RHO_V DR%TMP_D(ND,NF) = DR%TMP_D(ND,NF) + 0.5_EB*DN%TMP_V DR%CP_D(ND,NF) = DR%CP_D(ND,NF) + 0.5_EB*DN%CP_V @@ -4832,7 +4889,7 @@ SUBROUTINE HVAC_UPDATE_QFAN(DUCTRUN_INDEX,NF) IF (DVEL > TWO_EPSILON_EB) NN = DU%NODE_INDEX(1) IF (DVEL < TWO_EPSILON_EB) NN = DU%NODE_INDEX(2) DN => DUCTNODE(NN) - IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) THEN !VENT node we can update the DR node first then the duct + IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) THEN !VENT node we can update the DR node first then the duct N_UPDATED(NN) = .TRUE. DR%RHO_N(DN%DUCTRUN_INDEX,NF) = DN%RHO_V DR%TMP_N(DN%DUCTRUN_INDEX,NF) = DN%TMP_V @@ -4854,7 +4911,7 @@ SUBROUTINE HVAC_UPDATE_QFAN(DUCTRUN_INDEX,NF) N_UPDATED(DU%NODE_INDEX(2)) = .TRUE. IF (N_UPDATED(DU%NODE_INDEX(1)) .AND. N_UPDATED(DU%NODE_INDEX(2))) THEN DN => DUCTNODE(DU%NODE_INDEX(1)) - IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) THEN + IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) THEN DR%RHO_N(DN%DUCTRUN_INDEX,NF) = 0.5_EB*DN%RHO_V DR%TMP_N(DN%DUCTRUN_INDEX,NF) = 0.5_EB*DN%TMP_V DR%CP_N(DN%DUCTRUN_INDEX,NF) = 0.5_EB*DN%CP_V @@ -4866,7 +4923,7 @@ SUBROUTINE HVAC_UPDATE_QFAN(DUCTRUN_INDEX,NF) DR%ZZ_D(DU%DUCTRUN_INDEX,NF,:) = 0.5_EB*DR%ZZ_N(DN%DUCTRUN_INDEX,NF,:) ENDIF DN => DUCTNODE(DU%NODE_INDEX(2)) - IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE) THEN + IF (DN%VENT .OR. DN%AMBIENT .OR. DN%LEAKAGE .OR. DN%GEOM) THEN DR%RHO_N(DN%DUCTRUN_INDEX,NF) = DR%RHO_N(DN%DUCTRUN_INDEX,NF) + 0.5_EB*DN%RHO_V DR%TMP_N(DN%DUCTRUN_INDEX,NF) = DR%TMP_N(DN%DUCTRUN_INDEX,NF) + 0.5_EB*DN%TMP_V DR%CP_N(DN%DUCTRUN_INDEX,NF) = DR%CP_N(DN%DUCTRUN_INDEX,NF) + 0.5_EB*DN%CP_V diff --git a/Source/init.f90 b/Source/init.f90 index 6f7a9e58447..40997c7313b 100644 --- a/Source/init.f90 +++ b/Source/init.f90 @@ -2854,7 +2854,6 @@ SUBROUTINE INIT_WALL_CELL(NM,I,J,K,OBST_INDEX,IW,IOR,SURF_INDEX,IERR) VENT_SEARCH_LOOP: DO N=1,M%N_VENT VT => M%VENTS(N) - IF (VT%GEOM) CYCLE VENT_SEARCH_LOOP IF (OBST_INDEX>0) THEN IF (VT%BOUNDARY_TYPE==OPEN_BOUNDARY) CYCLE VENT_SEARCH_LOOP IF (.NOT.M%OBSTRUCTION(OBST_INDEX)%ALLOW_VENT) CYCLE VENT_SEARCH_LOOP diff --git a/Source/main.f90 b/Source/main.f90 index 368846399bf..a38a3485abe 100644 --- a/Source/main.f90 +++ b/Source/main.f90 @@ -184,6 +184,8 @@ PROGRAM FDS ENDDO IF (MY_RANK==0 .AND. VERBOSE) CALL VERBOSE_PRINTOUT('Completed INITIALIZE_WALL_ARRAY') +CALL PROC_HVAC + ! Write the Smokeview (.smv) file using parallel MPI writes CALL WRITE_SMOKEVIEW_FILE diff --git a/Source/read.f90 b/Source/read.f90 index ba54fd89b63..cf4fe98f31a 100644 --- a/Source/read.f90 +++ b/Source/read.f90 @@ -16,7 +16,7 @@ MODULE READ_INPUT USE MEMORY_FUNCTIONS, ONLY: ChkMemErr,REALLOCATE2D,REALLOCATE USE COMP_FUNCTIONS, ONLY: GET_INPUT_FILE USE MISC_FUNCTIONS, ONLY: SEARCH_CONTROLLER,WRITE_SUMMARY_INFO,GET_RAMP_INDEX,GET_SPEC_OR_SMIX_INDEX -USE HVAC_ROUTINES, ONLY: READ_HVAC,PROC_HVAC +USE HVAC_ROUTINES, ONLY: READ_HVAC!,PROC_HVAC USE COMPLEX_GEOMETRY, ONLY: READ_GEOM USE MPI_F08 USE THERMO_PROPS @@ -146,7 +146,7 @@ SUBROUTINE READ_DATA(DT) CALL PROC_REAC_2 ; CALL CHECK_STOP_STATUS ; IF (STOP_STATUS/=NO_STOP) RETURN CALL PROC_MATL ; CALL CHECK_STOP_STATUS ; IF (STOP_STATUS/=NO_STOP) RETURN CALL PROC_SURF_2 ; CALL CHECK_STOP_STATUS ; IF (STOP_STATUS/=NO_STOP) RETURN -CALL PROC_HVAC ; CALL CHECK_STOP_STATUS ; IF (STOP_STATUS/=NO_STOP) RETURN +!CALL PROC_HVAC ; CALL CHECK_STOP_STATUS ; IF (STOP_STATUS/=NO_STOP) RETURN CALL READ_CLIP ; CALL CHECK_STOP_STATUS ; IF (STOP_STATUS/=NO_STOP) RETURN CALL PROC_WALL ; CALL CHECK_STOP_STATUS ; IF (STOP_STATUS/=NO_STOP) RETURN CALL PROC_PART ; CALL CHECK_STOP_STATUS ; IF (STOP_STATUS/=NO_STOP) RETURN @@ -7780,7 +7780,7 @@ SUBROUTINE READ_SURF(QUICK_READ) CHARACTER(LABEL_LENGTH), DIMENSION(10) :: INIT_IDS LOGICAL :: ADIABATIC,BURN_AWAY,FREE_SLIP,NO_SLIP,CONVERT_VOLUME_TO_MASS,HORIZONTAL,DIRICHLET_FRONT,DIRICHLET_BACK, BLOWING, & INERT_Q_REF,ALLOW_UNDERSIDE_PARTICLES,ALLOW_SURFACE_PARTICLES -CHARACTER(LABEL_LENGTH) :: TEXTURE_MAP,HEAT_TRANSFER_MODEL,LEAK_PATH_ID(2) +CHARACTER(LABEL_LENGTH) :: TEXTURE_MAP,HEAT_TRANSFER_MODEL,LEAK_PATH_ID(2),NODE_ID CHARACTER(25) :: COLOR REAL(EB) :: TAU_Q,TAU_V,TAU_T,TAU_MF(MAX_SPECIES),HRRPUA,MLRPUA,TEXTURE_WIDTH,TEXTURE_HEIGHT,VEL_T(2),& TAU_EF,E_COEFFICIENT,VOLUME_FLOW,& @@ -7829,7 +7829,7 @@ SUBROUTINE READ_SURF(QUICK_READ) MATL_ID,MATL_MASS_FRACTION,MASS_PER_VOLUME,MCC_CONVERSION_FACTOR,MINIMUM_BURNOUT_TIME,& MINIMUM_LAYER_THICKNESS,MLRPUA,MOISTURE_FRACTION,& N_LAYER_CELLS_MAX,NEAR_WALL_EDDY_VISCOSITY,NEAR_WALL_TURBULENCE_MODEL,NET_HEAT_FLUX,& - NO_SLIP,NPPC,NUSSELT_C0,NUSSELT_C1,NUSSELT_C2,NUSSELT_M,& + NO_SLIP,NODE_ID,NPPC,NUSSELT_C0,NUSSELT_C1,NUSSELT_C2,NUSSELT_M,& PARTICLE_EXTRACTION_VELOCITY,PARTICLE_MASS_FLUX,PARTICLE_SURFACE_DENSITY,PART_ID,& PLE,PROFILE,RADIUS,RAMP_EF,RAMP_HEAT_TRANSFER_COEFFICIENT,RAMP_HEAT_TRANSFER_COEFFICIENT_BACK,RAMP_IHS,RAMP_MF,& RAMP_PART,RAMP_Q,RAMP_T,RAMP_T_I,RAMP_TMP_BACK,RAMP_TMP_GAS_BACK,RAMP_TMP_GAS_FRONT,& @@ -8504,6 +8504,7 @@ SUBROUTINE READ_SURF(QUICK_READ) CALL GET_RAMP_INDEX(RAMP_HEAT_TRANSFER_COEFFICIENT,'TIME',SF%RAMP_H_FIXED_INDEX) IF (RAMP_HEAT_TRANSFER_COEFFICIENT_BACK/='null') & CALL GET_RAMP_INDEX(RAMP_HEAT_TRANSFER_COEFFICIENT,'TIME',SF%RAMP_H_FIXED_B_INDEX) + SF%NODE_ID = NODE_ID SF%NUSSELT_C0 = NUSSELT_C0 SF%NUSSELT_C1 = NUSSELT_C1 SF%NUSSELT_C2 = NUSSELT_C2 @@ -8988,6 +8989,7 @@ SUBROUTINE SET_SURF_DEFAULTS NEAR_WALL_TURBULENCE_MODEL = 'null' NEAR_WALL_EDDY_VISCOSITY = -1._EB NO_SLIP = .FALSE. +NODE_ID = 'null' NPPC = 1 NUSSELT_C0 = -1._EB NUSSELT_C1 = -1._EB @@ -9096,7 +9098,7 @@ END SUBROUTINE READ_SURF SUBROUTINE PROC_SURF_1 -INTEGER :: N,NR,ILPC +INTEGER :: N,NN,NR,ILPC TYPE (LAGRANGIAN_PARTICLE_CLASS_TYPE), POINTER :: LPC PROCESS_SURF_LOOP: DO N=0,N_SURF @@ -9179,6 +9181,19 @@ SUBROUTINE PROC_SURF_1 ENDIF ENDDO + IF (SF%NODE_ID/='null') THEN + DO NN=1,N_DUCTNODES + IF (DUCTNODE(NN)%ID==SF%NODE_ID) THEN + SF%NODE_INDEX = NN + EXIT + ENDIF + ENDDO + IF (SF%NODE_INDEX==0) THEN + WRITE(MESSAGE,'(A,A,A)') 'ERROR(xxx): SURF ',TRIM(SF%ID),' NODE_ID does not exist' + CALL SHUTDOWN(MESSAGE) ; RETURN + ENDIF + ENDIF + ENDDO PROCESS_SURF_LOOP ! If a particle class uses a SURF line, make sure the SURF ID exists @@ -9601,7 +9616,7 @@ SUBROUTINE PROC_SURF_2 SF%SPECIES_BC_INDEX = INFLOW_OUTFLOW_MASS_FLUX SF%VELOCITY_BC_INDEX = INTERPOLATED_VELOCITY_BC ENDIF - IF (N==HVAC_SURF_INDEX) THEN + IF (N==HVAC_SURF_INDEX .OR. SF%NODE_ID/='null') THEN SF%THERMAL_BC_INDEX = HVAC_BOUNDARY SF%SPECIES_BC_INDEX = HVAC_BOUNDARY SF%EMISSIVITY = 1._EB @@ -11045,6 +11060,13 @@ SUBROUTINE READ_OBST(QUICK_READ) IF (SURF_ID6(5) ==SURFACE(NNN)%ID) OB%SURF_INDEX(-3) = NNN IF (SURF_ID6(6) ==SURFACE(NNN)%ID) OB%SURF_INDEX( 3) = NNN ENDDO + + DO NNN=-3,3 + IF (SURFACE(OB%SURF_INDEX(NNN))%NODE_ID/='null') THEN + WRITE(MESSAGE,'(A,A,A)') 'ERROR(xxx): OBST_ID ',TRIM(ID),' cannot have a SURF with NODE_ID.' + CALL SHUTDOWN(MESSAGE,PROCESS_0_ONLY=.FALSE.) ; RETURN + ENDIF + ENDDO ! If the obstruction is assigned a SURF with 3-D heat transfer (HT3D), adjust the nominal layer thickness for this ! surface. Storage arrays for WALL and THIN_WALL are based on the maximum thickness. @@ -11822,14 +11844,14 @@ SUBROUTINE READ_VENT CHARACTER(LABEL_LENGTH) :: ID,DEVC_ID,CTRL_ID,SURF_ID,PRESSURE_RAMP,TMP_EXTERIOR_RAMP,MULT_ID,OBST_ID CHARACTER(25) :: COLOR TYPE(MULTIPLIER_TYPE), POINTER :: MR -LOGICAL :: REJECT_VENT,OUTLINE,GEOM,SOLID_FOUND,AREA_ADJUST,BLOCKED +LOGICAL :: REJECT_VENT,OUTLINE,SOLID_FOUND,AREA_ADJUST,BLOCKED TYPE IMPLICIT_VENT_TYPE REAL(EB) :: XB(6) INTEGER, DIMENSION(3) :: RGB=-1 CHARACTER(LABEL_LENGTH) :: MB='null',SURF_ID='null',ID='null' END TYPE TYPE(IMPLICIT_VENT_TYPE), ALLOCATABLE, DIMENSION(:) :: IMPLICIT_VENT -NAMELIST /VENT/ AREA_ADJUST,COLOR,CTRL_ID,DB,DEVC_ID,DYNAMIC_PRESSURE,FYI,GEOM,ID,IOR,L_EDDY,L_EDDY_IJ, & +NAMELIST /VENT/ AREA_ADJUST,COLOR,CTRL_ID,DB,DEVC_ID,DYNAMIC_PRESSURE,FYI,ID,IOR,L_EDDY,L_EDDY_IJ, & MB,MULT_ID,N_EDDY,OBST_ID,OUTLINE,PBX,PBY,PBZ,PRESSURE_RAMP,RADIUS,REYNOLDS_STRESS, & RGB,SPREAD_RATE,SURF_ID,TEXTURE_ORIGIN,TMP_EXTERIOR,TMP_EXTERIOR_RAMP,TRANSPARENCY, & UVW,VEL_RMS,XB,XYZ @@ -12112,10 +12134,6 @@ SUBROUTINE READ_VENT IF (BLOCKED) REJECT_VENT = .TRUE. ENDIF - ! If the VENT is on a GEOM do not reject (further setup in READ_GEOM) - - IF (GEOM .AND. .NOT.(TERRAIN_CASE .AND. ALL(XB(1:6)>-1.01E6_EB))) REJECT_VENT = .FALSE. - ! If the VENT is rejected, cycle IF (REJECT_VENT) THEN @@ -12190,6 +12208,10 @@ SUBROUTINE READ_VENT DO NNN=0,N_SURF IF (SURF_ID==SURFACE(NNN)%ID) VT%SURF_INDEX = NNN ENDDO + IF (SURFACE(VT%SURF_INDEX)%NODE_ID /='null') THEN + WRITE(MESSAGE,'(3A)') 'ERROR(812): VENT ',TRIM(ID),' Use SURF_ID HVAC instead of NODE_ID.' + CALL SHUTDOWN(MESSAGE,PROCESS_0_ONLY=.FALSE.) ; RETURN + ENDIF IF (SURF_ID=='OPEN') VT%TYPE_INDICATOR = 2 IF (SURF_ID=='MIRROR' .OR. SURF_ID=='PERIODIC') VT%TYPE_INDICATOR = -2 @@ -12198,11 +12220,11 @@ SUBROUTINE READ_VENT IF (SURF_ID=='PERIODIC FLOW ONLY') VT%SURF_INDEX = PERIODIC_FLOW_ONLY_SURF_INDEX VT%BOUNDARY_TYPE = SOLID_BOUNDARY - IF (VT%SURF_INDEX==OPEN_SURF_INDEX) VT%BOUNDARY_TYPE = OPEN_BOUNDARY - IF (VT%SURF_INDEX==MIRROR_SURF_INDEX) VT%BOUNDARY_TYPE = MIRROR_BOUNDARY - IF (VT%SURF_INDEX==PERIODIC_SURF_INDEX) VT%BOUNDARY_TYPE = PERIODIC_BOUNDARY - IF (VT%SURF_INDEX==PERIODIC_FLOW_ONLY_SURF_INDEX) VT%BOUNDARY_TYPE = PERIODIC_BOUNDARY - IF (VT%SURF_INDEX==HVAC_SURF_INDEX) VT%BOUNDARY_TYPE = HVAC_BOUNDARY + IF (VT%SURF_INDEX==OPEN_SURF_INDEX) VT%BOUNDARY_TYPE = OPEN_BOUNDARY + IF (VT%SURF_INDEX==MIRROR_SURF_INDEX) VT%BOUNDARY_TYPE = MIRROR_BOUNDARY + IF (VT%SURF_INDEX==PERIODIC_SURF_INDEX) VT%BOUNDARY_TYPE = PERIODIC_BOUNDARY + IF (VT%SURF_INDEX==PERIODIC_FLOW_ONLY_SURF_INDEX) VT%BOUNDARY_TYPE = PERIODIC_BOUNDARY + IF (VT%SURF_INDEX==HVAC_SURF_INDEX .OR. SURFACE(VT%SURF_INDEX)%NODE_ID/='null') VT%BOUNDARY_TYPE = HVAC_BOUNDARY VT%IOR = IOR VT%ORDINAL = N_EXPLICIT @@ -12330,8 +12352,6 @@ SUBROUTINE READ_VENT VT%UVW = VT%UVW/SQRT(VT%UVW(1)**2+VT%UVW(2)**2+VT%UVW(3)**2) ENDIF - VT%GEOM = GEOM - ENDDO I_MULT_LOOP ENDDO J_MULT_LOOP ENDDO K_MULT_LOOP @@ -12417,7 +12437,7 @@ SUBROUTINE READ_VENT ENDDO ENDIF - IF (VT%IOR==0 .AND. .NOT.VT%GEOM) THEN + IF (VT%IOR==0) THEN WRITE(MESSAGE,'(3A)') 'ERROR(818): VENT ',TRIM(VT%ID),' requires an orientation index, IOR.' CALL SHUTDOWN(MESSAGE,PROCESS_0_ONLY=.FALSE.) ; RETURN ENDIF @@ -12465,17 +12485,9 @@ SUBROUTINE READ_VENT ! Check UVW - IF (.NOT.VT%GEOM) THEN - IF (ABS(VT%UVW(ABS(VT%IOR))) < TWO_EPSILON_EB) THEN - WRITE(MESSAGE,'(3A)') 'ERROR(821): VENT ',TRIM(VT%ID),' cannot have normal component of UVW equal to 0.' - CALL SHUTDOWN(MESSAGE,PROCESS_0_ONLY=.FALSE.) ; RETURN - ENDIF - ENDIF - - ! Special treatment for coloring GEOM surface with HVAC_BOUNDARY - - IF (VT%GEOM .AND. VT%BOUNDARY_TYPE==HVAC_BOUNDARY) THEN - SURFACE(VT%SURF_INDEX)%RGB = (/0,128,0/) ! green + IF (ABS(VT%UVW(ABS(VT%IOR))) < TWO_EPSILON_EB) THEN + WRITE(MESSAGE,'(3A)') 'ERROR(821): VENT ',TRIM(VT%ID),' cannot have normal component of UVW equal to 0.' + CALL SHUTDOWN(MESSAGE,PROCESS_0_ONLY=.FALSE.) ; RETURN ENDIF ENDDO VENT_LOOP_2 @@ -12548,7 +12560,6 @@ SUBROUTINE SET_VENT_DEFAULTS DB = 'null' DEVC_ID = 'null' DYNAMIC_PRESSURE = 0._EB -GEOM = .FALSE. ID = 'null' IOR = 0 L_EDDY = 0._EB diff --git a/Source/type.f90 b/Source/type.f90 index 8c6dcc73c79..73a5ea1c4e9 100644 --- a/Source/type.f90 +++ b/Source/type.f90 @@ -123,6 +123,7 @@ MODULE TYPES INTEGER :: DRAG_LAW=1 !< Code indicating type of drag law INTEGER :: DEVC_INDEX=0 !< Index of device that governs this class of particles INTEGER :: CTRL_INDEX=0 !< Index of controller that governs this class of particles + INTEGER :: NODE_INDEX=0 !< Index of ductnode for surface INTEGER :: ORIENTATION_INDEX=0 !< Starting position of the particle class orientation vector within the master array INTEGER :: N_ORIENTATION !< Number of orientations (directions) corresponding to this class of particles INTEGER :: Z_INDEX=-1 !< Species mixture index for this class @@ -934,6 +935,7 @@ MODULE TYPES INTEGER :: N_LPC=0 !< Number of particle classes emitted by the surface INTEGER :: N_CONE_CURVES=0 !< Total number of time vs. heat release rate curves specified for the S-pyro model INTEGER :: N_MATL !< Total number of unique materials over all layers + INTEGER :: NODE_INDEX=0 !< Ductnode index INTEGER, DIMENSION(30) :: ONE_D_REALS_ARRAY_SIZE=0,ONE_D_INTEGERS_ARRAY_SIZE=0,ONE_D_LOGICALS_ARRAY_SIZE=0 INTEGER, ALLOCATABLE, DIMENSION(:) :: N_LAYER_CELLS !< Number of wall cells per material layer INTEGER, ALLOCATABLE, DIMENSION(:) :: LAYER_INDEX !< The layer each wall cell belongs to @@ -954,16 +956,17 @@ MODULE TYPES REAL(EB), ALLOCATABLE, DIMENSION(:) :: MIN_DIFFUSIVITY REAL(EB), ALLOCATABLE, DIMENSION(:) :: HEAT_SOURCE REAL(EB), ALLOCATABLE, DIMENSION(:) :: LAYER_THICKNESS - REAL(EB), ALLOCATABLE, DIMENSION(:) :: MIN_LAYER_THICKNESS ! Smallest layer size before layer is removed (m) + REAL(EB), ALLOCATABLE, DIMENSION(:) :: MIN_LAYER_THICKNESS !< Smallest layer size before layer is removed (m) LOGICAL, ALLOCATABLE, DIMENSION(:) :: HT3D_LAYER REAL(EB), ALLOCATABLE, DIMENSION(:) :: CELL_SIZE_FACTOR - REAL(EB), ALLOCATABLE, DIMENSION(:) :: CELL_SIZE !< Specified constant cell size (m) + REAL(EB), ALLOCATABLE, DIMENSION(:) :: CELL_SIZE !< Specified constant cell size (m) REAL(EB), ALLOCATABLE, DIMENSION(:) :: STRETCH_FACTOR REAL(EB), DIMENSION(MAX_LAYERS) :: LAYER_DENSITY,& MOISTURE_FRACTION,SURFACE_VOLUME_RATIO,PACKING_RATIO,KAPPA_S=-1._EB,RENODE_DELTA_T REAL(EB), DIMENSION(MAX_LAYERS,MAX_MATERIALS) :: DENSITY_ADJUST_FACTOR=1._EB,RHO_S CHARACTER(LABEL_LENGTH), ALLOCATABLE, DIMENSION(:) :: MATL_NAME CHARACTER(LABEL_LENGTH), DIMENSION(MAX_LAYERS,MAX_MATERIALS) :: MATL_ID + CHARACTER(LABEL_LENGTH) :: NODE_ID='null' !< ID of a duct node REAL(EB), DIMENSION(MAX_LAYERS,MAX_MATERIALS) :: MATL_MASS_FRACTION LOGICAL :: BURN_AWAY,ADIABATIC,USER_DEFINED=.TRUE., & FREE_SLIP=.FALSE.,NO_SLIP=.FALSE.,SPECIFIED_NORMAL_VELOCITY=.FALSE.,SPECIFIED_TANGENTIAL_VELOCITY=.FALSE., & @@ -1142,7 +1145,7 @@ MODULE TYPES CHARACTER(LABEL_LENGTH) :: ID,MATL_ID,DEVC_ID,MOVE_ID CHARACTER(LABEL_LENGTH), ALLOCATABLE, DIMENSION(:) :: SURF_ID,VENT_ID CHARACTER(LABEL_LENGTH) :: GEOC_FILENAME='null',TEXTURE_MAPPING - LOGICAL :: COMPONENT_ONLY,IS_DYNAMIC=.TRUE.,HAVE_SURF,HAVE_VENT,HAVE_MATL,HIDDEN,REMOVEABLE,SHOW_BNDF=.TRUE., & + LOGICAL :: COMPONENT_ONLY,IS_DYNAMIC=.TRUE.,HAVE_SURF,HAVE_MATL,HIDDEN,REMOVEABLE,SHOW_BNDF=.TRUE., & READ_BINARY=.FALSE.,IS_TERRAIN=.FALSE. INTEGER :: N_VERTS_BASE,N_FACES_BASE,N_VOLUS_BASE,N_VERTS,N_EDGES,N_FACES,N_VOLUS,NSUB_GEOMS,GEOM_TYPE,IJK(3),N_LEVELS,& DEVC_INDEX=-1,CTRL_INDEX=-1,PROP_INDEX=-1,DEVC_INDEX_O=-1,CTRL_INDEX_O=-1,MATL_INDEX=-1,& @@ -1335,7 +1338,7 @@ MODULE TYPES INTEGER :: B2_INDEX=0 !< Derived type carrying most of the surface boundary conditions INTEGER :: BR_INDEX=0 !< Derived type carrying angular-specific radiation intensities INTEGER :: SURF_INDEX=0 - INTEGER :: VENT_INDEX=0 + INTEGER :: NODE_INDEX=0 INTEGER :: BOUNDARY_TYPE=0 INTEGER :: CUT_FACE_IND1=-11 !< First index pointing to CUT_FACE array for this CFACE. INTEGER :: CUT_FACE_IND2=-11 !< Second index pointing to CUT_FACE array for this CFACE. @@ -1493,7 +1496,7 @@ MODULE TYPES X1_ORIG=0._EB,X2_ORIG=0._EB,Y1_ORIG=0._EB,Y2_ORIG=0._EB,Z1_ORIG=0._EB,Z2_ORIG=0._EB, & X0=-9.E6_EB,Y0=-9.E6_EB,Z0=-9.E6_EB,FIRE_SPREAD_RATE,UNDIVIDED_INPUT_AREA=0._EB,INPUT_AREA=0._EB,& TMP_EXTERIOR=-1000._EB,DYNAMIC_PRESSURE=0._EB,UVW(3)=-1.E12_EB,RADIUS=-1._EB - LOGICAL :: ACTIVATED=.TRUE.,GEOM=.FALSE.,AREA_ADJUST=.TRUE.,DRAW=.TRUE. + LOGICAL :: ACTIVATED=.TRUE.,AREA_ADJUST=.TRUE.,DRAW=.TRUE. CHARACTER(LABEL_LENGTH) :: DEVC_ID='null',CTRL_ID='null',ID='null' ! turbulent inflow (experimental) INTEGER :: N_EDDY=0 @@ -1873,10 +1876,10 @@ MODULE TYPES LOGICAL :: AMBIENT = .FALSE. !< Node is connected to the ambient LOGICAL :: LEAKAGE=.FALSE. !< Node is being used for leakage LOGICAL :: VENT=.FALSE. !< Node has an attached vent + LOGICAL :: GEOM=.FALSE. !< Node has an attached GEOM LOGICAL :: HMT_FILTER=.FALSE. !< Filter is in mass transport ductrun LOGICAL :: TRANSPORT_PARTICLES=.FALSE. !< Particles will be transported through the vent attached to the node LOGICAL :: SPECIFIED_XYZ=.FALSE. !< Node has explicit XYZ. - LOGICAL, ALLOCATABLE, DIMENSION(:) :: IN_MESH !< (i) Flag indicating node is present in mesh i END TYPE DUCTNODE_TYPE TYPE (DUCTNODE_TYPE), DIMENSION(:), ALLOCATABLE, TARGET :: DUCTNODE