!========================================================================= ! 二次元トレーサー移流モデル: 時間増分計算モジュール ! ! 履歴 1997/10/16 小高正嗣 ! 1997/10/22 小高正嗣 ! 1997/11/13 小高正嗣 ! 1997/11/18 小高正嗣 !========================================================================= MODULE cal_module USE param_module PUBLIC CONTAINS !========================================================================= SUBROUTINE get_dtrc1_C2_2D( u, v, TRC, DTRC )! 二次中央差分 REAL,DIMENSION(:,:),INTENT(in) :: u REAL,DIMENSION(:,:),INTENT(in) :: v REAL,DIMENSION(0:,0:),INTENT(in):: TRC REAL,DIMENSION(0:,0:),INTENT(out):: DTRC INTEGER :: dim, xdim, ydim REAL,DIMENSION(:,:),ALLOCATABLE :: FLUX_X! フラックス1 REAL,DIMENSION(:,:),ALLOCATABLE :: FLUX_Y! フラックス2 REAL,DIMENSION(:,:),ALLOCATABLE :: ADVE_X! 移流項1 REAL,DIMENSION(:,:),ALLOCATABLE :: ADVE_Y! 移流項2 REAL,DIMENSION(:,:),ALLOCATABLE :: TRCM_X! 変数(半整数値1) REAL,DIMENSION(:,:),ALLOCATABLE :: TRCM_Y! 変数(半整数値2) xdim = SIZE( TRC, 1 ) - 1 ydim = SIZE( TRC, 2 ) - 1 dim = xdim - 1 ALLOCATE( TRCM_X(xdim,0:ydim), TRCM_Y(0:xdim,ydim) ) ALLOCATE( FLUX_X(xdim,ydim), FLUX_Y(xdim,ydim) ) ALLOCATE( ADVE_X(0:xdim,0:ydim), ADVE_Y(0:xdim,0:ydim) ) CALL get_mval_2D( TRC, TRCM_X, TRCM_Y ) FLUX_X = u * TRCM_X(:,1:) FLUX_Y = v * TRCM_Y(1:,:) ADVE_X(1:dim,1:dim) = - ( FLUX_X(2:,:dim) - FLUX_X(:dim,:dim) )/dx ADVE_Y(1:dim,1:dim) = - ( FLUX_Y(:dim,2:) - FLUX_Y(:dim,:dim) )/dy call bound2( ADVE_X ) call bound2( ADVE_Y ) DTRC = dt * ( ADVE_X + ADVE_Y ) DEALLOCATE( TRCM_X, TRCM_Y, FLUX_X, FLUX_Y, ADVE_X, ADVE_Y ) END SUBROUTINE get_dtrc1_C2_2D !========================================================================= SUBROUTINE get_dtrc1_C4_2D( u, v, TRC, DTRC )! 四次中央差分 REAL,DIMENSION(:,:),INTENT(in) :: u REAL,DIMENSION(:,:),INTENT(in) :: v REAL,DIMENSION(0:,0:),INTENT(in):: TRC REAL,DIMENSION(0:,0:),INTENT(out):: DTRC INTEGER :: dim, xdim, ydim REAL,DIMENSION(:,:),ALLOCATABLE :: FLUX_X! フラックス1 REAL,DIMENSION(:,:),ALLOCATABLE :: FLUX_Y! フラックス2 REAL,DIMENSION(:,:),ALLOCATABLE :: ADVE_X! 移流項1 REAL,DIMENSION(:,:),ALLOCATABLE :: ADVE_Y! 移流項2 REAL,DIMENSION(:,:),ALLOCATABLE :: TRCM_X! 変数(半整数値1) REAL,DIMENSION(:,:),ALLOCATABLE :: TRCM_Y! 変数(半整数値2) xdim = SIZE( TRC, 1 ) - 1 ydim = SIZE( TRC, 2 ) - 1 dim = xdim - 1 ALLOCATE( TRCM_X(xdim,0:ydim), TRCM_Y(0:xdim,ydim) ) ALLOCATE( FLUX_X(0:xdim+1,ydim), FLUX_Y(xdim,0:ydim+1) ) ALLOCATE( ADVE_X(0:xdim,0:ydim), ADVE_Y(0:xdim,0:ydim) ) CALL get_mval_2D( TRC, TRCM_X, TRCM_Y ) FLUX_X(1:xdim,:) = u * TRCM_X(:,1:) FLUX_Y(:,1:ydim) = v * TRCM_Y(1:,:) FLUX_X(0,:) = FLUX_X(2,:) FLUX_X(xdim+1,:) = FLUX_X(dim,:) FLUX_Y(:,0) = FLUX_Y(:,2) FLUX_Y(:,ydim+1) = FLUX_Y(:,dim) ADVE_X(1:dim,1:dim) = & & ( - 1.125 * ( FLUX_X(2:xdim,1:dim) - FLUX_X(1:dim,1:dim) ) & & + 0.125/3.* ( FLUX_X(3:,1:dim) - FLUX_X(:dim-1,1:dim) ) )/dx ADVE_Y(1:dim,1:dim) = & & ( - 1.125 * ( FLUX_Y(1:dim,2:ydim) - FLUX_Y(1:dim,1:dim) ) & & + 0.125/3.* ( FLUX_Y(1:dim,3:) - FLUX_Y(1:dim,:dim-1) ) )/dy call bound2( ADVE_X ) call bound2( ADVE_Y ) DTRC = dt * ( ADVE_X + ADVE_Y ) DEALLOCATE( TRCM_X, TRCM_Y, FLUX_X, FLUX_Y, ADVE_X, ADVE_Y ) END SUBROUTINE get_dtrc1_C4_2D !========================================================================= SUBROUTINE get_dtrc_u1_2D( u, v, TRC, DTRC )! 上流差分 REAL,DIMENSION(:,:),INTENT(in) :: u REAL,DIMENSION(:,:),INTENT(in) :: v REAL,DIMENSION(0:,0:),INTENT(in):: TRC REAL,DIMENSION(0:,0:),INTENT(out):: DTRC INTEGER :: dim, xdim, ydim REAL,DIMENSION(:,:),ALLOCATABLE :: FLUX_X! フラックス1 REAL,DIMENSION(:,:),ALLOCATABLE :: FLUX_Y! フラックス2 REAL,DIMENSION(:,:),ALLOCATABLE :: ADVE_X! 移流項1 REAL,DIMENSION(:,:),ALLOCATABLE :: ADVE_Y! 移流項2 xdim = SIZE( TRC, 1 ) - 1 ydim = SIZE( TRC, 2 ) - 1 dim = xdim - 1 ALLOCATE( FLUX_X(xdim,ydim), FLUX_Y(xdim,ydim) ) ALLOCATE( ADVE_X(0:xdim,0:ydim), ADVE_Y(0:xdim,0:ydim) ) FLUX_X = MAX( u, 0. )*TRC(:dim,1:) + MIN( u, 0. )*TRC(1:,1:) FLUX_Y = MAX( v, 0. )*TRC(1:,:dim) + MIN( v, 0. )*TRC(1:,1:) ADVE_X(1:dim,1:dim) = - ( FLUX_X(2:,:dim) - FLUX_X(:dim,:dim) )/dx ADVE_Y(1:dim,1:dim) = - ( FLUX_Y(:dim,2:) - FLUX_Y(:dim,:dim) )/dy call bound2( ADVE_X ) call bound2( ADVE_Y ) DTRC = dt * ( ADVE_X + ADVE_Y ) DEALLOCATE( FLUX_X, FLUX_Y, ADVE_X, ADVE_Y ) END SUBROUTINE get_dtrc_u1_2D !========================================================================= SUBROUTINE get_dtrc_u_mpdata_2D( u, v, TRC, udif, vdif, DTRC )! MPDATA 上流差分 REAL,DIMENSION(:,:),INTENT(in) :: u REAL,DIMENSION(:,:),INTENT(in) :: v REAL,DIMENSION(0:,0:),INTENT(in):: TRC REAL,DIMENSION(:,:),INTENT(out) :: udif REAL,DIMENSION(:,:),INTENT(out) :: vdif REAL,DIMENSION(0:,0:),INTENT(out):: DTRC INTEGER :: dim, xdim, ydim REAL,DIMENSION(:,:),ALLOCATABLE :: FLUX_X! フラックス1 REAL,DIMENSION(:,:),ALLOCATABLE :: FLUX_Y! フラックス2 REAL,DIMENSION(:,:),ALLOCATABLE :: ADVE_X! 移流項1 REAL,DIMENSION(:,:),ALLOCATABLE :: ADVE_Y! 移流項2 REAL,DIMENSION(:,:),ALLOCATABLE :: TRCM_X! 変数(半整数値1) REAL,DIMENSION(:,:),ALLOCATABLE :: TRCM_Y! 変数(半整数値2) REAL,PARAMETER :: epsilon = 1.e-4 xdim = SIZE( TRC, 1 ) - 1 ydim = SIZE( TRC, 2 ) - 1 dim = xdim - 1 ALLOCATE( FLUX_X(xdim,ydim), FLUX_Y(xdim,ydim) ) ALLOCATE( ADVE_X(0:xdim,0:ydim), ADVE_Y(0:xdim,0:ydim) ) ALLOCATE( TRCM_X(xdim,0:ydim), TRCM_Y(0:xdim,ydim) ) CALL get_mval_2D( TRC, TRCM_X, TRCM_Y ) udif = 0. vdif = 0. DO i = 1, xdim DO j = 1, ydim IF ( TRCM_X(i,j) /= 0. ) THEN udif(i,j) = 0.5*ABS(u(i,j)) * ( TRC(i,j) - TRC(i-1,j) ) & & / ( TRCM_X(i,j) ) END IF IF ( TRCM_Y(i,j) /= 0. ) THEN vdif(i,j) = 0.5*ABS(v(i,j)) * ( TRC(i,j) - TRC(i,j-1) ) & & / ( TRCM_Y(i,j) ) END IF END DO END DO FLUX_X = MAX( udif, 0. )*TRC(:dim,1:) + MIN( udif, 0. )*TRC(1:,1:) FLUX_Y = MAX( vdif, 0. )*TRC(1:,:dim) + MIN( vdif, 0. )*TRC(1:,1:) ADVE_X(1:dim,1:dim) = - ( FLUX_X(2:,:dim) - FLUX_X(:dim,:dim) )/dx ADVE_Y(1:dim,1:dim) = - ( FLUX_Y(:dim,2:) - FLUX_Y(:dim,:dim) )/dy call bound2( ADVE_X ) call bound2( ADVE_Y ) DTRC = dt * ( ADVE_X + ADVE_Y ) DEALLOCATE( FLUX_X, FLUX_Y, ADVE_X, ADVE_Y ) END SUBROUTINE get_dtrc_u_mpdata_2D !========================================================================= SUBROUTINE get_mval_2D( val, mval_x, mval_y ) REAL,DIMENSION(0:,0:),INTENT(in):: val REAL,DIMENSION(:,0:),INTENT(out):: mval_x REAL,DIMENSION(0:,:),INTENT(out):: mval_y INTEGER :: xdim,ydim xdim = SIZE( mval_x, 1 ) ydim = SIZE( mval_y, 2 ) mval_x = ( val(1:,:) + val(:xdim-1,:) )/2 mval_y = ( val(:,1:) + val(:,:ydim-1) )/2 END SUBROUTINE get_mval_2D !========================================================================= SUBROUTINE get_plotval( val, pval ) REAL,DIMENSION(0:,0:),INTENT(in):: val REAL,DIMENSION(:,:),INTENT(out) :: pval INTEGER :: xdim,ydim xdim = SIZE( pval, 1 ) ydim = SIZE( pval, 2 ) pval = (val(1:,1:) + val(1:,:ydim-1) + & & val(:xdim-1,1:) + val(:xdim-1,:ydim-1) )/4. END SUBROUTINE get_plotval !========================================================================= SUBROUTINE bound2( val ) REAL,DIMENSION(0:,0:),INTENT(inout):: val INTEGER :: dim,xdim,ydim xdim = SIZE( val, 1 ) - 1 ydim = SIZE( val, 2 ) - 1 dim = xdim - 1 !-cyclic ! val(0,:) = val(dim,:) ! val(xdim,:) = val(1,:) ! val(:,0) = val(:,dim) ! val(:,ydim) = val(:,1) ! val(0,0) = val(dim,dim) ! val(0,ydim) = val(dim,1) ! val(xdim,0) = val(1,dim) ! val(xdim,ydim) = val(1,1) !-fixed boundary (symmetric) val(0,:) = val(1,:) val(xdim,:) = val(dim,:) val(:,0) = val(:,1) val(:,ydim) = val(:,dim) val(0,0) = val(1,1) val(0,ydim) = val(1,dim) val(xdim,0) = val(dim,1) val(xdim,ydim) = val(dim,dim) ! END SUBROUTINE bound2 !========================================================================= END MODULE cal_module