⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 func.f90

📁 FDS为火灾动力学模拟软件源代码,该软件为开源项目,代码语言主要为FORTRAN,可在WINDOWS和LINUX下编译运行,详细说明可参考http://fire.nist.gov/fds/官方网址
💻 F90
📖 第 1 页 / 共 3 页
字号:
MODULE COMP_FUNCTIONS! I/O + OS functionsUSE PRECISION_PARAMETERS IMPLICIT NONE CHARACTER(255), PARAMETER :: funcid='$Id: func.f90 713 2007-09-28 21:44:10Z mcgratta $'CHARACTER(255), PARAMETER :: funcrev='$Revision: 713 $'CHARACTER(255), PARAMETER :: funcdate='$Date: 2007-09-28 17:44:10 -0400 (Fri, 28 Sep 2007) $' CONTAINSSUBROUTINE GET_REV_func(MODULE_REV,MODULE_DATE)INTEGER,INTENT(INOUT) :: MODULE_REVCHARACTER(255),INTENT(INOUT) :: MODULE_DATEWRITE(MODULE_DATE,'(A)') funcrev(INDEX(funcrev,':')+1:LEN_TRIM(funcrev)-2)READ (MODULE_DATE,'(I5)') MODULE_REVWRITE(MODULE_DATE,'(A)') funcdateEND SUBROUTINE GET_REV_funcREAL(EB) FUNCTION SECOND()  ! Returns the CPU time in seconds.REAL(FB) CPUTIMECALL CPU_TIME(CPUTIME)SECOND = CPUTIMEEND FUNCTION SECONDREAL(EB) FUNCTION WALL_CLOCK_TIME()  ! Returns the number of seconds since January 1, 2000, including leap years! Thirty days hath September,! April, June, and November.! February has twenty-eight alone;! All the rest have thirty-one,! Excepting Leap-Year, that's the time! When February's days are twenty-nine.INTEGER :: DATE_TIME(8),WALL_CLOCK_SECONDSCHARACTER(10) :: BIG_BEN(3)! X_1 = common year, X_2 = leap yearINTEGER, PARAMETER :: S_PER_YEAR_1=31536000,S_PER_YEAR_2=31622400,S_PER_DAY=86400,S_PER_HOUR=3600,S_PER_MIN=60INTEGER, PARAMETER, DIMENSION(12) :: ACCUMULATED_DAYS_1=(/0,31,59,90,120,151,181,212,243,273,304,334/), &                                      ACCUMULATED_DAYS_2=(/0,31,60,91,121,152,182,213,244,274,305,335/)INTEGER :: YEAR_COUNTCALL DATE_AND_TIME(BIG_BEN(1),BIG_BEN(2),BIG_BEN(3),DATE_TIME)WALL_CLOCK_SECONDS = 0._EBDO YEAR_COUNT=2001,DATE_TIME(1)   !Leap year if divisible by 4 but not 100 unless by 400 (1900 no, 1904  yes, 2000 yes)   IF (MOD(YEAR_COUNT,4)==0 .AND. (MOD(YEAR_COUNT,100)/=0 .OR. MOD(YEAR_COUNT,400)==0)) THEN      WALL_CLOCK_SECONDS = WALL_CLOCK_SECONDS + S_PER_YEAR_2   ELSE      WALL_CLOCK_SECONDS = WALL_CLOCK_SECONDS + S_PER_YEAR_1   ENDIFENDDO IF (MOD(DATE_TIME(1),4)==0 .AND. (MOD(DATE_TIME(1),100)/=0 .OR. MOD(DATE_TIME(1),400)==0 )) THEN   WALL_CLOCK_SECONDS = WALL_CLOCK_SECONDS + S_PER_DAY*(ACCUMULATED_DAYS_2(DATE_TIME(2))+DATE_TIME(3))ELSE   WALL_CLOCK_SECONDS = WALL_CLOCK_SECONDS + S_PER_DAY*(ACCUMULATED_DAYS_1(DATE_TIME(2))+DATE_TIME(3))ENDIFWALL_CLOCK_SECONDS = WALL_CLOCK_SECONDS +  S_PER_HOUR*DATE_TIME(5) + S_PER_MIN*DATE_TIME(6) + DATE_TIME(7)WALL_CLOCK_TIME    = WALL_CLOCK_SECONDS + DATE_TIME(8)*0.001_EBEND FUNCTION WALL_CLOCK_TIMESUBROUTINE SHUTDOWN(MESSAGE)  ! Stops the code gracefully after writing a messageUSE GLOBAL_CONSTANTS, ONLY: LU_ERRCHARACTER(*) MESSAGEWRITE(LU_ERR,'(/A)') TRIM(MESSAGE)STOPEND SUBROUTINE SHUTDOWN !!SUBROUTINE FLUSH_BUFFER(UNIT) ! FLUSH_BUFFER flushes the buffer for the named logical unit.!!USE IFPORT  ! For Intel compilers!!USE GLOBAL_CONSTANTS, ONLY: FLUSH_FILE_BUFFERS!!INTEGER, INTENT(IN) :: UNIT!!IF (FLUSH_FILE_BUFFERS) CALL FLUSH(UNIT)!!END SUBROUTINE FLUSH_BUFFER SUBROUTINE GET_INPUT_FILE ! Read the argument after the commandUSE GLOBAL_CONSTANTS, ONLY: FN_INPUTIF (FN_INPUT=='null') CALL GETARG(1,FN_INPUT)END SUBROUTINE GET_INPUT_FILESUBROUTINE CHECKREAD(NAME,LU,IOS) INTEGER :: II,IOSINTEGER, INTENT(IN) :: LUCHARACTER(4), INTENT(IN) :: NAMECHARACTER(80) TEXT IOS = 1READLOOP: DO   READ(LU,'(A)',END=10) TEXT   TLOOP: DO II=1,72      IF (TEXT(II:II)/='&' .AND. TEXT(II:II)/=' ') EXIT TLOOP      IF (TEXT(II:II)=='&') THEN         IF (TEXT(II+1:II+4)==NAME) THEN            BACKSPACE(LU)            IOS = 0            EXIT READLOOP         ELSE            CYCLE READLOOP         ENDIF      ENDIF   ENDDO TLOOPENDDO READLOOP 10 RETURNEND SUBROUTINE CHECKREADEND MODULE COMP_FUNCTIONSMODULE MEMORY_FUNCTIONSUSE PRECISION_PARAMETERSUSE MESH_VARIABLESUSE COMP_FUNCTIONS, ONLY : SHUTDOWNIMPLICIT NONECONTAINSSUBROUTINE ChkMemErr(CodeSect,VarName,IZERO) ! Memory checking routine CHARACTER(*), INTENT(IN) :: CodeSect, VarNameINTEGER IZEROCHARACTER(100) MESSAGE IF (IZERO==0) RETURN WRITE(MESSAGE,'(4A)') 'ERROR: Memory allocation failed for ', TRIM(VarName),' in the routine ',TRIM(CodeSect)CALL SHUTDOWN(MESSAGE)END SUBROUTINE ChkMemErrSUBROUTINE RE_ALLOCATE_DROPLETS(CODE,NM,NOM,NEW_DROPS) TYPE (DROPLET_TYPE), ALLOCATABLE, DIMENSION(:) :: DUMMYINTEGER, INTENT(IN) :: CODE,NM,NOM,NEW_DROPSTYPE (MESH_TYPE), POINTER :: MTYPE(OMESH_TYPE), POINTER :: M2 SELECT CASE(CODE)   CASE(1)      M=>MESHES(NM)      ALLOCATE(DUMMY(1:M%NLPDIM))      DUMMY = M%DROPLET      DEALLOCATE(M%DROPLET)      ALLOCATE(M%DROPLET(M%NLPDIM+NEW_DROPS))      M%DROPLET(1:M%NLPDIM) = DUMMY(1:M%NLPDIM)      M%NLPDIM = M%NLPDIM+NEW_DROPS   CASE(2)      M2=>MESHES(NM)%OMESH(NOM)      ALLOCATE(DUMMY(1:M2%N_DROP_ORPHANS_DIM))      DUMMY = M2%DROPLET      DEALLOCATE(M2%DROPLET)      ALLOCATE(M2%DROPLET(M2%N_DROP_ORPHANS_DIM+NEW_DROPS))      M2%DROPLET(1:M2%N_DROP_ORPHANS_DIM) = DUMMY(1:M2%N_DROP_ORPHANS_DIM)      M2%N_DROP_ORPHANS_DIM = M2%N_DROP_ORPHANS_DIM + NEW_DROPSEND SELECTDEALLOCATE(DUMMY)END SUBROUTINE RE_ALLOCATE_DROPLETS FUNCTION REALLOCATE(P,N1,N2)          REAL(EB), POINTER, DIMENSION(:) :: P, REALLOCATEINTEGER, INTENT(IN) :: N1,N2INTEGER :: NOLD, IERRCHARACTER(100) :: MESSAGEALLOCATE(REALLOCATE(N1:N2), STAT=IERR)IF (IERR /= 0) THEN   WRITE(MESSAGE,'(A)') 'ERROR: Memory allocation failed in REALLOCATE'   CALL SHUTDOWN(MESSAGE)ENDIFIF (.NOT. ASSOCIATED(P)) RETURNNOLD = MIN(SIZE(P), N2-N1+1)REALLOCATE(N1:NOLD+N1-1) = P(N1:NOLD+N1-1)  ! Restore the contents of the reallocated arrayDEALLOCATE(P) END FUNCTION REALLOCATESUBROUTINE RE_ALLOCATE_STRINGS(NM) CHARACTER(50), ALLOCATABLE, DIMENSION(:) :: DUMMYINTEGER, INTENT(IN) :: NMTYPE (MESH_TYPE), POINTER :: M M=>MESHES(NM)ALLOCATE(DUMMY(1:M%N_STRINGS))DUMMY = M%STRINGDEALLOCATE(M%STRING)ALLOCATE(M%STRING(M%N_STRINGS_MAX+100))M%STRING(1:M%N_STRINGS) = DUMMY(1:M%N_STRINGS)M%N_STRINGS_MAX = M%N_STRINGS_MAX+100DEALLOCATE(DUMMY) END SUBROUTINE RE_ALLOCATE_STRINGSEND MODULE MEMORY_FUNCTIONS MODULE GEOMETRY_FUNCTIONS! Functions for manipulating geometryUSE PRECISION_PARAMETERSUSE MESH_VARIABLESUSE GLOBAL_CONSTANTSIMPLICIT NONE CONTAINS SUBROUTINE BLOCK_CELL(NM,I1,I2,J1,J2,K1,K2,IVAL,OBST_INDEX)! Indicate which cells are blocked off INTEGER :: NM,I1,I2,J1,J2,K1,K2,IVAL,I,J,K,OBST_INDEX,ICTYPE (MESH_TYPE), POINTER :: M M => MESHES(NM)DO K=K1,K2   DO J=J1,J2      DO I=I1,I2         IC = M%CELL_INDEX(I,J,K)         SELECT CASE(IVAL)            CASE(0)                M%SOLID(IC)        = .FALSE.               M%OBST_INDEX_C(IC) = 0            CASE(1)               M%SOLID(IC)        = .TRUE.               M%OBST_INDEX_C(IC) = OBST_INDEX         END SELECT      ENDDO   ENDDOENDDO END SUBROUTINE BLOCK_CELL  SUBROUTINE GET_N_LAYER_CELLS(DIFFUSIVITY,THICKNESS,STRETCH_FACTOR,CELL_SIZE_FACTOR,N_CELLS,DXMIN)! Get number of wall cells in the layerINTEGER, INTENT(OUT)  :: N_CELLSREAL(EB), INTENT(OUT) :: DXMINREAL(EB), INTENT(IN)  :: DIFFUSIVITY,THICKNESS,STRETCH_FACTOR,CELL_SIZE_FACTORREAL(EB) :: DSUMINTEGER  :: N, IIF (THICKNESS.EQ.0._EB) THEN   N_CELLS = 0   DXMIN = 0._EB   RETURNENDIFSHRINK_LOOP: DO N=1,999   DSUM = 0._EB   SUM_LOOP: DO I=1,N      DSUM = DSUM + STRETCH_FACTOR**(MIN(I-1,N-I))   ENDDO SUM_LOOP   IF ((THICKNESS/DSUM < CELL_SIZE_FACTOR*SQRT(DIFFUSIVITY)) .OR. (N==999)) THEN      N_CELLS = N      DXMIN = THICKNESS/DSUM      EXIT SHRINK_LOOP   ENDIFENDDO SHRINK_LOOPEND SUBROUTINE GET_N_LAYER_CELLSSUBROUTINE GET_WALL_NODE_COORDINATES(N_CELLS,N_LAYERS,N_LAYER_CELLS, &         SMALLEST_CELL_SIZE,STRETCH_FACTOR,X_S)! Get the wall internal coordinatesINTEGER, INTENT(IN)     :: N_CELLS,N_LAYERS, N_LAYER_CELLS(N_LAYERS)REAL(EB), INTENT(IN)    :: SMALLEST_CELL_SIZE(N_LAYERS),STRETCH_FACTORREAL(EB), INTENT(OUT)   :: X_S(0:N_CELLS)INTEGER I, II, NLREAL(EB) DX_S   II = 0   X_S(0) = 0._EB   DO NL=1,N_LAYERS      DO I=1,N_LAYER_CELLS(NL)         II = II+1         DX_S = SMALLEST_CELL_SIZE(NL)*STRETCH_FACTOR**(MIN(I-1,N_LAYER_CELLS(NL)-I))         X_S(II) = X_S(II-1) + DX_S      ENDDO   ENDDOEND SUBROUTINE GET_WALL_NODE_COORDINATESSUBROUTINE GET_WALL_NODE_WEIGHTS(N_CELLS,N_LAYERS,N_LAYER_CELLS, &         THICKNESS,GEOMETRY,X_S,DX,RDX,RDXN,DX_WGT,DXF,DXB,LAYER_INDEX)! Get the wall internal coordinatesINTEGER, INTENT(IN)     :: N_CELLS, N_LAYERS, N_LAYER_CELLS(N_LAYERS), GEOMETRYREAL(EB), INTENT(IN)    :: X_S(0:N_CELLS),THICKNESSINTEGER, INTENT(OUT)    :: LAYER_INDEX(0:N_CELLS+1)REAL(EB), INTENT(OUT)   :: DX(1:N_CELLS),RDX(0:N_CELLS+1),RDXN(0:N_CELLS),DX_WGT(0:N_CELLS),DXF,DXBINTEGER I, II, NL, I_GRADREAL(EB) RSELECT CASE(GEOMETRY)CASE(SURF_CARTESIAN)   I_GRAD = 0CASE(SURF_CYLINDRICAL)   I_GRAD = 1CASE(SURF_SPHERICAL)   I_GRAD = 2END SELECT   II = 0   DO NL=1,N_LAYERS      DO I=1,N_LAYER_CELLS(NL)         II = II + 1         LAYER_INDEX(II) = NL      ENDDO   ENDDO   LAYER_INDEX(0) = 1   LAYER_INDEX(N_CELLS+1) = N_LAYERS   DXF = X_S(1)       - X_S(0)   DXB = X_S(N_CELLS) - X_S(N_CELLS-1)! Compute dx_weight for each node (dx_weight is the ratio of cell size to the ! combined size of the current and next cell)   DO I=1,N_CELLS-1      DX_WGT(I) = (X_S(I)-X_S(I-1))/(X_S(I+1)-X_S(I-1))   ENDDO   DX_WGT(0)       = 0.5_EB   DX_WGT(N_CELLS) = 0.5_EB! Compute dx and 1/dx for each node (dx is the distance from cell boundary to cell boundary)   DO I=1,N_CELLS      DX(I)  = X_S(I)-X_S(I-1)      RDX(I) = 1._EB/DX(I)   ENDDO  ! Adjust 1/dx_n to 1/rdr for cylindrical case and 1/r^2dr for spaherical   IF (GEOMETRY /=SURF_CARTESIAN) THEN      DO I=1,N_CELLS         R = THICKNESS-0.5_EB*(X_S(I)+X_S(I-1))         RDX(I) = RDX(I)/R**I_GRAD      ENDDO   ENDIF   RDX(0)         = RDX(1)   RDX(N_CELLS+1) = RDX(N_CELLS)! Compute 1/dx_n for each node (dx_n is the distance from cell center to cell center)   DO I=1,N_CELLS-1      RDXN(I) = 2._EB/(X_S(I+1)-X_S(I-1))   ENDDO   RDXN(0)       = 1._EB/(X_S(1)-X_S(0))   RDXN(N_CELLS) = 1._EB/(X_S(N_CELLS)-X_S(N_CELLS-1))! Adjust 1/dx_n to r/dr for cylindrical case and r^2/dr for spaherical   IF (GEOMETRY /= SURF_CARTESIAN) THEN      DO I=0,N_CELLS         R = THICKNESS-X_S(I)         RDXN(I) = RDXN(I)*R**I_GRAD      ENDDO   ENDIFEND SUBROUTINE GET_WALL_NODE_WEIGHTSSUBROUTINE GET_INTERPOLATION_WEIGHTS(N_LAYERS,NWP,NWP_NEW,N_LAYER_CELLS,N_LAYER_CELLS_NEW, &            X_S,X_S_NEW,INT_WGT)INTEGER, INTENT(IN)  :: N_LAYERS,NWP,NWP_NEW,N_LAYER_CELLS(N_LAYERS),N_LAYER_CELLS_NEW(N_LAYERS)REAL(EB), INTENT(IN) :: X_S(0:NWP), X_S_NEW(0:NWP_NEW)REAL(EB), INTENT(OUT) :: INT_WGT(NWP_NEW,NWP)REAL(EB) XUP,XLOW,XUP_NEW,XLOW_NEW,DX_NEWINTEGER I, J, II, JJ, I_BASE, J_BASE, J_OLD,NII = 0JJ = 0I_BASE = 0J_BASE = 0INT_WGT = 0._EBDO N = 1,N_LAYERS   J_OLD = 1   DO I = 1,N_LAYER_CELLS_NEW(N)      II       = I_BASE + I      XUP_NEW  = X_S_NEW(II)      XLOW_NEW = X_S_NEW(II-1)      DX_NEW   = XUP_NEW - XLOW_NEW       DO J = J_OLD,N_LAYER_CELLS(N)         JJ = J_BASE + J         XUP =  X_S(JJ)         XLOW = X_S(JJ-1)         INT_WGT(II,JJ) = (MIN(XUP,XUP_NEW)-MAX(XLOW,XLOW_NEW))/DX_NEW         IF (XUP .GE. XUP_NEW) EXIT      ENDDO      J_OLD = J   ENDDO   I_BASE = I_BASE + N_LAYER_CELLS_NEW(N)   J_BASE = J_BASE + N_LAYER_CELLS(N)ENDDOEND SUBROUTINE GET_INTERPOLATION_WEIGHTSSUBROUTINE INTERPOLATE_WALL_ARRAY(NWP,NWP_NEW,INT_WGT,ARR)INTEGER, INTENT(IN)  :: NWP,NWP_NEWREAL(EB), INTENT(IN) :: INT_WGT(NWP_NEW,NWP)REAL(EB) ARR(NWP),TMP(NWP)INTEGER I,JTMP = ARRARR = 0._EBDO I = 1,NWP_NEWDO J = 1,NWP   ARR(I) = ARR(I) + INT_WGT(I,J)*TMP(J)ENDDOENDDOEND SUBROUTINE INTERPOLATE_WALL_ARRAYEND MODULE GEOMETRY_FUNCTIONS  MODULE PHYSICAL_FUNCTIONS! Functions for physical quantitiesUSE PRECISION_PARAMETERSUSE GLOBAL_CONSTANTSUSE MESH_VARIABLESIMPLICIT NONECONTAINSSUBROUTINE GET_F_C(Z_1,Z_2,Z_3,F,C,Z_F)!Returns progress variables for Mixture Fraction functions for suppression and CO productionREAL(EB) :: Z_F,WGT,Z_3_MAX,ZZREAL(EB), INTENT(IN) :: Z_1,Z_2,Z_3REAL(EB), INTENT(OUT) :: F,CINTEGER :: IZ1,IZ2

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -