XBeach
C:/repositories/XBeach/trunk/src/xbeachlibrary/flow_secondorder.F90
Go to the documentation of this file.
00001 !==============================================================================
00002 !                               FLOW_SECONDORDER_MODULE
00003 !==============================================================================
00004 !
00005 ! DATE               AUTHOR               CHANGES
00006 !
00007 ! october 2009       Pieter Bart Smit     New module
00008 !
00009 !******************************************************************************
00010 !                                 INTERFACE
00011 !******************************************************************************
00012 
00013 module flow_secondorder_module
00014 
00015    implicit none
00016    save
00017    private
00018 
00019    !----------------------------- PARAMETERS -----------------------------------
00020 
00021    include 'nh_pars.inc'               !Default precision etc.
00022 
00023    !----------------------------- VARIABLES  -----------------------------------
00024 
00025 
00026    real(kind=rKind),dimension(:,:),allocatable  :: wrk1 !Temporary storage for:
00027    !    (i )  du-velocity at i    ,j+1/2
00028    !    (ii)  dv-velocity at i    ,j+1/2
00029    !    (iii) dqx         at i+1/2,j
00030    real(kind=rKind),dimension(:,:),allocatable  :: wrk2 !Temporary storage for:
00031    !    (i )  du-velocity at i+1/2,j
00032    !    (ii)  dv-velocity at i+1/2,j
00033    !    (iii) dqx         at i    ,j+1/2
00034 
00035    logical                                      :: initialized = .false.
00036 
00037    public flow_secondorder_advUV
00038    public flow_secondorder_advW
00039    public flow_secondorder_con
00040    public minmod
00041    public  flow_secondorder_huhv
00042    !
00043    !******************************************************************************
00044    !                             SUBROUTINES/FUNCTIONS
00045    !******************************************************************************
00046 
00047 contains
00048 
00049    subroutine flow_secondorder_init(s)
00050       !
00051 
00052       !-------------------------------------------------------------------------------
00053       !                             DECLARATIONS
00054       !-------------------------------------------------------------------------------
00055 
00056       !
00057       !--------------------------        PURPOSE         ----------------------------
00058       !
00059       !   Initializes the resources needed for the second order mcCormack scheme
00060       !
00061       !
00062       !--------------------------     DEPENDENCIES       ----------------------------
00063       !
00064       !
00065       ! -- MODULES --
00066       use spaceparams
00067 
00068       !
00069       !--------------------------     ARGUMENTS          ----------------------------
00070       !
00071       type(spacepars)    ,intent(inout) :: s
00072 
00073       !Allocate resources
00074       allocate (  wrk1(s%nx+1,s%ny+1))
00075       allocate (  wrk2(s%nx+1,s%ny+1))
00076 
00077       wrk1   = 0.0_rKind
00078       wrk2   = 0.0_rKind
00079 
00080       initialized = .true.
00081    end subroutine flow_secondorder_init
00082 
00083    !
00084    !==============================================================================
00085    subroutine flow_secondorder_advUV(s,par,uu_old,vv_old)
00086       !==============================================================================
00087       !
00088 
00089       ! DATE               AUTHOR               CHANGES
00090       !
00091       ! November 2010       Pieter Bart Smit     New Subroutine
00092       ! November 2014       Pieter Bart Smit     Updated for curvilinear and mpi
00093 
00094       !-------------------------------------------------------------------------------
00095       !                             DECLARATIONS
00096       !-------------------------------------------------------------------------------
00097 
00098       !
00099       !--------------------------        PURPOSE         ----------------------------
00100       !
00101       !   Calculates second order correction to the advection terms for U and V
00102       !
00103 
00104       !
00105       !--------------------------     DEPENDENCIES       ----------------------------
00106       !
00107       use spaceparams
00108       use params,         only: parameters
00109 
00110       !
00111       !--------------------------      METHOD            ----------------------------
00112       !
00113       ! First a prediction for the velocity on the new timelevel is done in flow_timestep
00114       ! using an explicit first order euler step. We use this prediction (s%uu,s%vv), and the velocity
00115       ! at the beginning of the step (uu_old, vv_old), to do a slope limited correction.
00116       !
00117 
00118       !
00119       !--------------------------     ARGUMENTS          ----------------------------
00120       !
00121       type(spacepars)  ,intent(inout)  :: s
00122       type(parameters) ,intent(in)     :: par
00123 
00124       real(kind=rkind),dimension(s%nx+1,s%ny+1),intent(in) :: vv_old  !"Old" v-velocity
00125       real(kind=rkind),dimension(s%nx+1,s%ny+1),intent(in) :: uu_old  !"Old" u-velocity
00126       !
00127 
00128       !--------------------------     LOCAL VARIABLES    ----------------------------
00129       !
00130       integer(kind=iKind)        :: iww  !i-2 :Two points 'west' of current point i
00131       integer(kind=iKind)        :: iw   !i-1 :One ...
00132       integer(kind=iKind)        :: i    !Current point
00133       integer(kind=iKind)        :: ie   !i+1
00134       integer(kind=iKind)        :: iee  !i+2
00135       integer(kind=iKind)        :: jnn  !j-2
00136       integer(kind=iKind)        :: jn   !j-1
00137       integer(kind=iKind)        :: j    !Current point
00138       integer(kind=iKind)        :: js   !j+1
00139       integer(kind=iKind)        :: jss  !j+2
00140       integer(kind=iKind)        :: jmin1d,jmax1d,jmin,jmax,imin,imax  ! index for superfast1D
00141 
00142       real(kind=rKind)           :: mindepth ! Near the dry/wet interface the higher order interpolations
00143       ! can cause unwanted effects. To avoid this any extrapolation/interpolation
00144       ! is disabled when the lowest surface elevation within the molecule is lower then
00145       ! the highers bottom elevation.
00146 
00147       real(kind=rKind)           :: delta1   ! "Central" difference
00148       real(kind=rKind)           :: delta2   ! "Upwind"  difference
00149 
00150       real(kind=rKind)           :: qx,qy    !discharge south
00151       real(kind=rKind)           :: fac      !A factor
00152 
00153       !-------------------------------------------------------------------------------
00154       !                             IMPLEMENTATION
00155       !-------------------------------------------------------------------------------
00156 
00157       !Initialize/allocate arrays on first entry
00158       if (.not. initialized) then
00159          call flow_secondorder_init(s)
00160       endif
00161 
00162       !
00163       imin = 2
00164       if (xmpi_istop) then
00165          !
00166          imin = 3
00167          !
00168       endif
00169 
00170       imax = s%nx
00171       if (xmpi_isbot) then
00172          !
00173          imax = s%nx-1
00174          !
00175       endif
00176 
00177       jmin = 2
00178       if (xmpi_isleft) then
00179          !
00180          jmin = 3
00181          !
00182       endif
00183 
00184       jmax = s%ny
00185       if (xmpi_isright) then
00186          !
00187          jmax = s%ny-1
00188          !
00189       endif
00190 
00191       !
00192       if (s%ny>0) then
00193          !
00194          jmin1d = 2
00195          jmax1d = s%ny
00196          !
00197       else
00198          !
00199          jmin1d = 1
00200          jmax1d = 1
00201          !
00202       endif
00203 
00204       !
00205       !-- calculate qx * du in z-points --
00206       !
00207       do j=jmin1d,jmax1d
00208          !
00209          do i=2,s%nx
00210             !
00211             wrk1(i,j) = 0.0_rKind
00212             ie   = min(i+1,imax+1)
00213             iee  = min(i+2,imax+1)
00214             iw   = max(i-1,1)
00215             iww  = max(i-2,1)
00216             mindepth = minval(s%zs(iww:iee,j))-maxval(s%zb(iww:iee,j))
00217 
00218             qx = .5 * ( s%qx(i,j) + s%qx(iw,j) ) * cos( s%alfau( i ,j ) - s%alfau( iw,j) )
00219             !
00220             if (mindepth > par%eps) then
00221                !
00222                if   ( qx > 0.d0 .and. i>imin )    then
00223                   !
00224                   delta1    = (s%uu(i,j) -uu_old(iw ,j)) / s%dsz(i,j)
00225                   delta2    = (s%uu(iw,j)-uu_old(iww,j)) / s%dsz(iw,j)
00226                   wrk1(i,j) = 0.5d0*s%dsu(iw,j) * minmod(delta1,delta2) * qx
00227                   !
00228                elseif ( qx < 0.d0 .and. i < imax + 1  ) then
00229                   !
00230                   delta1    = (uu_old(i,j) -s%uu(iw ,j)) / s%dsz(i,j)
00231                   delta2    = (uu_old(ie,j)-s%uu(i,j))   / s%dsz(ie,j)
00232                   wrk1(i,j) = -0.5d0*s%dsu(i,j) * minmod(delta1,delta2) *qx
00233                   !
00234                endif
00235                !
00236             endif
00237             !
00238          enddo
00239          !
00240       enddo
00241 
00242       !
00243       !-- calculate qy * du in c-points --
00244       !
00245       if ( s%ny > 0 ) then
00246          !
00247          do j=2,s%ny
00248             !
00249             do i=2,s%nx-1
00250                !
00251                wrk2(i,j) = 0.0_rkind
00252                js   = min(j+1,jmax+1)
00253                jss  = min(j+2,jmax+1)
00254                jn   = max(j-1,1)
00255                mindepth = minval(s%zs(i:i+1,jn:jss))-maxval(s%zb(i:i+1,jn:jss))
00256                !
00257                if ((mindepth > par%eps)) then
00258                   !
00259                   qy = ( s%qy(i+1,j) + s%qy(i,j) ) * .5d0 * cos( s%alfau( i , j ) - s%alfau( i , j + 1 ) )
00260                   !
00261                   if ( qy  > 0.d0 .and. j > jmin - 1 ) then
00262                      !
00263                      delta1    = (s%uu(i,js) -uu_old(i ,j )) / s%dnv(i,j)
00264                      delta2    = (s%uu(i,j)  -uu_old(i ,jn)) / s%dnv(i,jn)
00265                      wrk2(i,j) = 0.5d0*s%dnv(i,j)*minmod(delta1,delta2) * qy
00266                      !
00267                   elseif ( qy < 0.d0 .and. j < jmax ) then
00268                      !
00269                      delta1    = (uu_old(i,js) -s%uu(i ,j)) / s%dnv(i,j)
00270                      delta2    = (uu_old(i,jss)-s%uu(i,js)) / s%dnv(i,js)
00271                      wrk2(i,j)   = -0.5d0*s%dnv(i,j)*minmod(delta1,delta2) * qy
00272                      !
00273                   endif
00274                endif
00275                !
00276             enddo
00277             !
00278          enddo
00279          !
00280          wrk2(:,1   ) = 0.0_rKind
00281          !
00282       endif
00283 
00284       !CORRECTION TO U
00285       if (s%ny>0) then
00286          !
00287          do j=jmin_uu,jmax_uu
00288             !
00289             do i=imin_uu,imax_uu
00290                !
00291                fac = par%dt / s%hum(i,j) * s%dsdnui(i,j)
00292                s%uu(i,j) = s%uu(i,j) - fac * ( s%dnz(i+1,j) *  wrk1(i+1,j) - s%dnz(i,  j) *  wrk1(i  ,j  ) &
00293                +   s%dsc(i,j  ) *  wrk2(i  ,j) - s%dsc(i,j-1) *  wrk2(i  ,j-1) )
00294                !
00295             enddo
00296             !
00297          enddo
00298          !
00299       else
00300          !
00301          do i=imin_uu,imax_uu
00302             !
00303             s%uu(i,1) = s%uu(i,1)-par%dt/s%hum(i,1)*(  ( wrk1(i+1,1) - wrk1(i  ,1  ) ) / s%dsu(i,1) )
00304             !
00305          enddo
00306          !
00307       endif
00308 
00309       !== SECOND ORDER EXPLICIT CORRECTION TO V ==
00310       if (s%ny>2) then
00311          !
00312          do j=2,s%ny
00313             !
00314             do i=2,s%nx
00315                !
00316                wrk1(i,j) = 0.
00317                js   = min(j+1,jmax+1)
00318                jss  = min(j+2,jmax+1)
00319                jn   = max(j-1,1)
00320                jnn  = max(j-2,1)
00321                mindepth = minval(s%zs(i,jnn:jss))-maxval(s%zb(i,jnn:jss))
00322                !
00323                qy = 0.5d0 * ( s%qy(i,j)+s%qy(i,jn) ) * cos( s%alfav(i,j) - s%alfav(i,jn) ) * s%dsz(i,j)
00324                !
00325                if (mindepth > par%eps) then
00326                   !
00327                   if   (( qy > 0.0) .and. (j>jmin)) then
00328                      !
00329                      delta1    = (s%vv(i,j ) - vv_old(i ,jn )) / s%dnz(i,j)
00330                      delta2    = (s%vv(i,jn) - vv_old(i ,jnn)) / s%dnz(i,jn)
00331                      wrk1(i,j)   = 0.5d0*s%dnv(i,jn)*minmod(delta1,delta2)*qy
00332                      !
00333                   elseif ( qy < -0.0d0 .and. j<jmax+1) then
00334                      !
00335                      delta1    = (vv_old(i,j ) - s%vv(i,jn)) / s%dnz(i,j)
00336                      delta2    = (vv_old(i,js) - s%vv(i,j )) / s%dnz(i,js)
00337                      wrk1(i,j)   = -0.5d0*s%dnv(i,j)*minmod(delta1,delta2)*qy
00338                      !
00339                   endif
00340                   !
00341                endif
00342             enddo
00343          enddo
00344 
00345          do j=2,s%ny-1
00346             !
00347             do i=2,s%nx
00348                !
00349                wrk2(i,j) = 0.0d0
00350                ie   = min(i+1,s%nx)
00351                iee  = min(i+2,s%nx)
00352                iw   = max(i-1,1)
00353                mindepth = minval(s%zs(iw:iee,j:j+1))-maxval(s%zb(iw:iee,j:j+1))
00354                !
00355                if (mindepth > par%eps) then
00356                   !
00357                   qx = .5d0 * ( s%qx(i,j+1) + s%qx(i,j) ) * cos( s%alfav( i , j ) - s%alfav( i + 1 , j ) ) * s%dsc(i,j)
00358                   !
00359                   if     ( qx > par%Umin .and. i > imin - 1) then
00360                      delta1    = (s%vv(ie,j) - vv_old(i ,j )) / s%dsu(i,1)
00361                      delta2    = (s%vv(i ,j) - vv_old(iw,j))  / s%dsu(iw,1)
00362                      wrk2(i,j) = 0.5d0*s%dsu(i,1)*minmod(delta1,delta2)*qx
00363                   elseif ( qx < -par%Umin .and. i < imax ) then
00364                      delta1    = (vv_old(ie,j) -s%vv(i ,j)) / s%dsu(ie,1)
00365                      delta2    = (vv_old(iee,j)-s%vv(ie,j)) / s%dsu(ie,1)
00366                      wrk2(i,j) = -0.5d0*s%dsu(i,1)*minmod(delta1,delta2)*qx
00367                   endif
00368                endif
00369             enddo
00370          enddo
00371          wrk2(1,:)    = 0.0_rKind
00372 
00373          !CORRECTION TO V
00374          do j=jmin_vv,jmax_vv
00375             !
00376             do i=imin_vv,imax_vv
00377                !
00378                fac = par%dt / s%hvm(i,j) * s%dsdnvi(i,j)
00379                s%vv(i,j) = s%vv(i,j) - fac*( wrk2(i,j) - wrk2(i-1,j) + wrk1(i,j+1) - wrk1(i  ,j) )
00380                !
00381             enddo
00382             !
00383          enddo
00384       endif
00385       !
00386    end subroutine flow_secondorder_advUV
00387 
00388    !
00389    !==============================================================================
00390    subroutine flow_secondorder_advW(s,par,w,w_old,mskZ)
00391       !==============================================================================
00392       !
00393 
00394       ! DATE               AUTHOR               CHANGES
00395       !
00396       ! November 2010       Pieter Bart Smit     New Subroutine
00397       ! November 2014       Pieter Bart Smit     Modified for nonhq3d
00398 
00399       !-------------------------------------------------------------------------------
00400       !                             DECLARATIONS
00401       !-------------------------------------------------------------------------------
00402 
00403       !
00404       !--------------------------        PURPOSE         ----------------------------
00405       !
00406       !   Calculates second order correction to the advection terms for W. Only used
00407       !   in combination WITH the non-hydrostatic module
00408 
00409       !--------------------------     DEPENDENCIES       ----------------------------
00410       !
00411 
00412       ! -- MODULES --
00413       use spaceparams
00414       use params,         only: parameters
00415       use xmpi_module
00416 
00417 
00418       !--------------------------     ARGUMENTS          ----------------------------
00419       !
00420 
00421       type(spacepars)  ,intent(inout)  :: s
00422       type(parameters) ,intent(in)     :: par
00423 
00424       real(kind=rKind),dimension(s%nx+1,s%ny+1),intent(inout) :: w      !The velocity at the star level
00425       real(kind=rKind),dimension(s%nx+1,s%ny+1),intent(in)    :: w_old  !The vertical velocity at the n-level
00426       integer(kind=iKind),dimension(s%nx+1,s%ny+1),intent(in) :: mskZ   !A mask that determines whether or not the w-equation is active
00427 
00428       !
00429       !--------------------------     LOCAL VARIABLES    ----------------------------
00430       !
00431       integer(kind=iKind)        :: iw   !i-1 :One ...
00432       integer(kind=iKind)        :: i    !Current point
00433       integer(kind=iKind)        :: ie   !i+1
00434       integer(kind=iKind)        :: iee  !i+2
00435       integer(kind=iKind)        :: jn   !j+1
00436       integer(kind=iKind)        :: jnn   !j+2
00437       integer(kind=iKind)        :: j    !Current point
00438       integer(kind=iKind)        :: js   !j-1
00439       integer(kind=iKind)        :: jmin,jmax,imin,imax
00440 
00441       real(kind=rKind)           :: rfac
00442       real(kind=rKind)           :: mindepth
00443       real(kind=rKind)           :: delta1
00444       real(kind=rKind)           :: delta2,qx,qy
00445 
00446       !-------------------------------------------------------------------------------
00447       !                             IMPLEMENTATION
00448       !-------------------------------------------------------------------------------
00449 
00450 
00451       !
00452       imin = 1
00453       if (xmpi_istop) then
00454          !
00455          imin = 2
00456          !
00457       endif
00458 
00459       imax = s%nx
00460       if (xmpi_isbot) then
00461          !
00462          imax = s%nx-1
00463          !
00464       endif
00465 
00466       jmin = 1
00467       if (xmpi_isleft) then
00468          !
00469          jmin = 2
00470          !
00471       endif
00472 
00473       jmax = s%ny
00474       if (xmpi_isright) then
00475          !
00476          jmax = s%ny-1
00477          !
00478       endif
00479       !
00480 
00481       !Initialize/allocate arrays on first entry
00482       if (.not. initialized) then
00483          !
00484          call flow_secondorder_init(s)
00485          !
00486       endif
00487 
00488       if (s%ny > 0) then
00489          !
00490          ! 2D Codepath
00491          !
00492 
00493          !
00494          ! Calculate the updated fluxes of w-mom. in the s-dir
00495          !
00496          wrk1 = 0.0d0
00497          do j=2,s%ny
00498             !
00499             do i=1,s%nx
00500                !
00501                if ( mskZ(i,j) == 0 ) cycle
00502 
00503                wrk1(i,j) = 0.0_rKind
00504                !
00505                ie   = min(i+1,imax+1)
00506                iee  = min(i+2,imax+1)
00507                iw   = max(i-1,1)
00508 
00509                rfac = real( mskZ( ie , j ) * mskZ( iee , j ) * mskZ( iw , j ), kind=rKind )
00510 
00511                mindepth = minval(s%zs(iw:iee,j))-maxval(s%zb(iw:iee,j))
00512                qx = s%qx(i,j) * s%dnu( i,j ) * rfac
00513                !
00514                if (mindepth > par%eps) then
00515                   !
00516                   if   ( qx > 0.0_rKind .and. i>imin ) then
00517                      !
00518                      delta1    = (w(ie,j ) - w_old(i  ,j )) / s%dsu(i,j)
00519                      delta2    = (w(i,j )  - w_old(iw ,j )) / s%dsu(iw,j)
00520                      wrk1(i,j)   = 0.5d0*s%dsu(i,j)*minmod(delta1,delta2) * qx
00521                      !
00522                   elseif (qx < 0.0_rKind .and. i<imax) then
00523                      !
00524                      delta1    = (w_old(ie ,j)  - w(i ,j )) / s%dsu(i,j)
00525                      delta2    = (w_old(iee,j ) - w(ie,j )) / s%dsu(ie,j)
00526                      wrk1(i,j) = -0.5d0*s%dsu(i,j)*minmod(delta1,delta2)*qx
00527                      !
00528                   endif
00529                   !
00530                endif
00531                !
00532             enddo
00533             !
00534          enddo
00535 
00536          !
00537          ! Calculate the updated fluxes of w-mom. in the n-dir
00538          !
00539          wrk2 = 0.
00540          do j=1,s%ny
00541             !
00542             do i=2,s%nx
00543                !
00544                if ( mskZ(i,j) == 0 ) cycle
00545 
00546                wrk2(i,j) = 0.0_rKind
00547                !
00548                jn   = min(j+1,jmax+1)
00549                jnn  = min(j+2,jmax+1)
00550                js   = max(j-1,1)
00551 
00552                rfac = real( mskZ( i , jn ) * mskZ( i , jnn ) * mskZ( i , js ), kind=rKind )
00553 
00554                mindepth = minval(s%zs(i,js:jnn))-maxval(s%zb(i,js:jnn))
00555                qy = s%qy(i,j) * s%dsv( i,j ) * rfac
00556                !
00557                if (mindepth > par%eps) then
00558                   !
00559                   if   ( qy > 0.0_rKind .and. j>jmin ) then
00560                      !
00561                      delta1    = (w(i,jn ) - w_old(i  ,j )) / s%dnv(i,j)
00562                      delta2    = (w(i,j )  - w_old(i ,js )) / s%dnv(i,js)
00563                      wrk2(i,j)   = 0.5d0*s%dnv(i,j)*minmod(delta1,delta2) * qy
00564                      !
00565                   elseif (qy < 0.0_rKind .and. j<jmax) then
00566                      !
00567                      delta1    = (w_old(i ,jn)  - w(i ,j )) / s%dnv(i,j)
00568                      delta2    = (w_old(i,jnn ) - w(i,jn )) / s%dnv(i,jn)
00569                      wrk2(i,j) = -0.5d0*s%dnv(i,j)*minmod(delta1,delta2)*qy
00570                      !
00571                   endif
00572                   !
00573                endif
00574                !
00575             enddo
00576             !
00577          enddo
00578          !
00579 
00580          !
00581          if (xmpi_istop) then
00582             !
00583             wrk1(1,:) = 0.0d0
00584             !
00585          endif
00586          if (xmpi_isbot) then
00587             !
00588             wrk1(s%nx,:) = 0.0d0
00589             !
00590          endif
00591          if (xmpi_isleft) then
00592             !
00593             wrk2(:,1) = 0.0d0
00594             !
00595          endif
00596          if (xmpi_isright) then
00597             !
00598             wrk2(:,s%ny) =0.
00599             !
00600          endif
00601          !
00602 
00603          !
00604          ! Update w-mom
00605          !
00606          do j=jmin_zs,jmax_zs
00607             !
00608             do i=imin_zs,imax_zs
00609                !
00610                if ( mskZ(i,j) == 0 ) cycle
00611                !
00612                w(i,j) = w(i,j) - par%dt * s%dsdnzi(i,j) *( wrk1(i,j) + wrk2(i,j) - wrk1(i-1,j) - wrk2(i,j-1) ) /s%hh(i,j)
00613                !
00614             enddo
00615             !
00616          enddo
00617          !
00618       else
00619          !
00620          ! 1D Codepath
00621          !
00622          j=1
00623          do i=2,s%nx
00624             !
00625             if ( mskZ(i,j) == 0 ) cycle
00626 
00627             wrk1(i,j) = 0.0_rKind
00628             !
00629             ie   = min(i+1,s%nx)
00630             iee  = min(i+2,s%nx)
00631             iw   = max(i-1,1)
00632 
00633             rfac = real( mskZ( ie , j ) * mskZ( iee , j ) * mskZ( iw , j ), kind=rKind )
00634 
00635             mindepth = minval(s%zs(iw:iee,j))-maxval(s%zb(iw:iee,j))
00636             qx = s%qx(i,j) * rfac
00637             !
00638             if (mindepth > par%eps) then
00639                !
00640                if   ( qx > 0.0_rKind .and. i>2 ) then
00641                   !
00642                   delta1    = (w(ie,j ) - w_old(i  ,j )) / s%dsu(i,j)
00643                   delta2    = (w(i,j )  - w_old(iw ,j )) / s%dsu(iw,j)
00644                   wrk1(i,j)   = 0.5d0*s%dsu(i,j)*minmod(delta1,delta2) * qx
00645                   !
00646                elseif (qx < 0.0_rKind .and. i<s%nx-1) then
00647                   !
00648                   delta1    = (w_old(ie ,j)  - w(i ,j )) / s%dsu(i,j)
00649                   delta2    = (w_old(iee,j ) - w(ie,j )) / s%dsu(ie,j)
00650                   wrk1(i,j)   = -0.5d0*s%dsu(i,j)*minmod(delta1,delta2)*qx
00651                   !
00652                endif
00653                !
00654             endif
00655             !
00656          enddo
00657 
00658          !
00659          if (xmpi_istop) then
00660             !
00661             wrk1(1,:) = 0.0d0
00662             !
00663          endif
00664          if (xmpi_isbot) then
00665             !
00666             wrk1(s%nx,:) = 0.0d0
00667             !
00668          endif
00669          !
00670          ! Update w-mom to ** level
00671          !
00672          do i=imin_zs,imax_zs
00673             !
00674             if ( mskZ(i,1) == 0 ) cycle
00675             !
00676             w(i,1) = w(i,1)-par%dt/s%hh(i,1)* ( wrk1(i,1)- wrk1(i-1,1) )/ s%dsz(i,1)
00677             !
00678          enddo
00679          !
00680       endif
00681       !
00682    end subroutine flow_secondorder_advW
00683 
00684    !
00685    !==============================================================================
00686    subroutine flow_secondorder_con(s,par,zs_old)
00687       !==============================================================================
00688       !
00689       ! DATE               AUTHOR               CHANGES
00690       !
00691       ! November 2010       Pieter Bart Smit     New Subroutine
00692 
00693       !-------------------------------------------------------------------------------
00694       !                             DECLARATIONS
00695       !-------------------------------------------------------------------------------
00696 
00697       !
00698       !--------------------------        PURPOSE         ----------------------------
00699       !
00700       !   Calculates second order correction to the continuity terms
00701       !
00702 
00703       !--------------------------     DEPENDENCIES       ----------------------------
00704       !
00705       use spaceparams
00706       use params,           only: parameters
00707 
00708       !--------------------------     ARGUMENTS          ----------------------------
00709       !
00710       type(spacepars)  ,intent(inout)  :: s
00711       type(parameters) ,intent(in)     :: par
00712 
00713       real(kind=rKind),dimension(s%nx+1,s%ny+1),intent(in) :: zs_old
00714       !
00715 
00716       !--------------------------     LOCAL VARIABLES    ----------------------------
00717       !
00718 
00719       integer(kind=iKind)        :: iw   !i-1 :One ...
00720       integer(kind=iKind)        :: i    !Current point
00721       integer(kind=iKind)        :: ie   !i+1
00722       integer(kind=iKind)        :: iee  !i+2
00723       integer(kind=iKind)        :: jn   !j-1
00724       integer(kind=iKind)        :: j    !Current point
00725       integer(kind=iKind)        :: js   !j+1
00726       integer(kind=iKind)        :: jss  !j+2
00727       integer(kind=iKind)        :: jmin,jmax  !index for superfast1D
00728 
00729       real(kind=rKind)           :: mindepth
00730       real(kind=rKind)           :: delta1
00731       real(kind=rKind)           :: delta2
00732       !-------------------------------------------------------------------------------
00733       !                             IMPLEMENTATION
00734       !-------------------------------------------------------------------------------
00735 
00736       if (s%ny>0) then
00737          jmin = 2
00738          jmax = s%ny
00739       else
00740          jmin = 1
00741          jmax = 1
00742       endif
00743 
00744       !== SECOND ORDER EXPLICIT CORRECTION TO CONTINUITY ==
00745       !Initialize/allocate arrays on first entry
00746       if (.not. initialized) then
00747          call flow_secondorder_init(s)
00748       endif
00749       !return
00750       !correction to mass flux qx
00751       do j=jmin,jmax
00752          do i=2,s%nx-1
00753             wrk1(i,j) = 0.0_rkind
00754             ie  = min(i+1,s%nx)
00755             iee = min(i+2,s%nx)
00756             iw  = max(i-1,2)
00757             mindepth = minval(s%zs(iw:iee,j))-maxval(s%zb(iw:iee,j))
00758             if (mindepth>par%eps) then
00759                if     (s%uu(i,j) >  par%umin .and. i>2     ) then
00760                   delta1    =  (s%zs(ie,j)- zs_old(i,j ))/ s%dsu(i,1)
00761                   delta2    =  (s%zs(i,j) - zs_old(iw,j))/ s%dsu(i-1,1)
00762                   wrk1(i,j)  =   s%uu(i,j)*0.5d0*s%dsu(i,1)*minmod(delta1,delta2)
00763                elseif (s%uu(i,j) < -par%umin .and. i<s%nx-1) then
00764                   delta1    =  (zs_old(iee,j) - s%zs(ie,j)) / s%dsu(i+1,1)
00765                   delta2    =  (zs_old(ie ,j) - s%zs(i ,j)) / s%dsu(i,1)
00766                   wrk1(i,j)  = - s%uu(i,j)*0.5d0*s%dsu(i,1)*minmod(delta1,delta2)
00767                endif
00768             endif
00769          enddo
00770       enddo
00771       wrk1(1   ,:) = 0.0_rkind
00772       wrk1(s%nx,:) = 0.0_rkind
00773 
00774       !Correction to mass flux qy
00775       if (s%ny > 2) then
00776          do j=2,s%ny-1
00777             do i=2,s%nx
00778                wrk2(i,j) = 0.0_rKind
00779                js  = min(j+1,s%ny)
00780                jss = min(j+2,s%ny)
00781                jn  = max(j-1,2)
00782                mindepth = minval(s%zs(i,jn:jss))-maxval(s%zb(i,jn:jss))
00783                if (mindepth> par%eps) then
00784                   if     (s%vv(i,j) >  par%Umin .and. j>2) then
00785                      delta1    = (s%zs(i,js) - zs_old(i,j ))/ s%dnv(1,j)
00786                      delta2    = (s%zs(i,j)  - zs_old(i,jn))/ s%dnv(1,j-1)
00787                      wrk2(i,j) =  s%vv(i,j)*0.5d0*s%dnv(1,j)*minmod(delta1,delta2)
00788                   elseif (s%vv(i,j) < -par%Umin .and. j<s%ny-1) then
00789                      delta1    = (zs_old(i,jss) - s%zs(i,js)) / s%dnv(1,j+1)
00790                      delta2    = (zs_old(i ,js) - s%zs(i ,j)) / s%dnv(1,j)
00791                      wrk2(i,j) =  s%vv(i,j)*0.5d0*s%dnv(1,j)*minmod(delta1,delta2)
00792                   endif
00793                endif
00794             enddo
00795          enddo
00796          wrk2(:,1   ) = 0.0_rKind
00797          wrk2(:,s%ny) = 0.0_rKind
00798       else
00799          wrk2 = 0.0_rKind
00800       endif
00801 
00802       !Update waterlevels
00803       if (s%ny>0) then
00804          do j=jmin_zs,jmax_zs
00805             do i=imin_zs,imax_zs
00806                s%zs(i,j) = s%zs(i,j)-par%dt*(  (wrk1(i,j)-wrk1(i-1,j))/ s%dsz(i,1)  &
00807                +  (wrk2(i,j)-wrk2(i,j-1))/ s%dnz(1,j)  )
00808             enddo
00809          enddo
00810       else
00811          do i=imin_zs,imax_zs
00812             s%zs(i,1) = s%zs(i,1)-par%dt*(  (wrk1(i,1)-wrk1(i-1,1))/ s%dsz(i,1) )
00813          enddo
00814       endif
00815 
00816       !Update fluxes
00817       if (s%ny>0) then
00818          s%qx(imin_uu:imax_uu,jmin_uu:jmax_uu) = s%qx(imin_uu:imax_uu,jmin_uu:jmax_uu) +wrk1(imin_uu:imax_uu,jmin_uu:jmax_uu)
00819          s%qy(imin_vv:imax_vv,jmin_vv:jmax_vv) = s%qy(imin_vv:imax_vv,jmin_vv:jmax_vv) +wrk2(imin_vv:imax_vv,jmin_vv:jmax_vv)
00820       else
00821          s%qx(imin_uu:imax_uu,jmin_uu:jmax_uu) = s%qx(imin_uu:imax_uu,jmin_uu:jmax_uu) +wrk1(imin_uu:imax_uu,jmin_uu:jmax_uu)
00822       endif
00823 
00824    end subroutine flow_secondorder_con
00825 
00826    !
00827    !==============================================================================
00828    subroutine flow_secondorder_huhv(s,par)
00829       !==============================================================================
00830       !
00831       ! DATE               AUTHOR               CHANGES
00832       !
00833       ! November 2014       Pieter Bart Smit     New Subroutine
00834 
00835       !-------------------------------------------------------------------------------
00836       !                             DECLARATIONS
00837       !-------------------------------------------------------------------------------
00838 
00839       !
00840       !--------------------------        PURPOSE         ----------------------------
00841       !
00842       !   Calculates second order correction to the waterlevels
00843       !
00844 
00845       !--------------------------     DEPENDENCIES       ----------------------------
00846       !
00847       use spaceparams
00848       use params,         only: parameters
00849       use xmpi_module
00850 
00851       !--------------------------     ARGUMENTS          ----------------------------
00852       !
00853       type(spacepars)  ,intent(inout)  :: s
00854       type(parameters) ,intent(in)     :: par
00855 
00856       !    real(kind=rKind),dimension(s%nx+1,s%ny+1),intent(in) :: zs_old
00857       !
00858 
00859       !--------------------------     LOCAL VARIABLES    ----------------------------
00860       !
00861 
00862       integer(kind=iKind)        :: iw   !i-1 :One ...
00863       integer(kind=iKind)        :: i    !Current point
00864       integer(kind=iKind)        :: ie   !i+1
00865       integer(kind=iKind)        :: iee  !i+2
00866       integer(kind=iKind)        :: j    !Current point
00867       integer(kind=iKind)        :: jmin,jmax,imin,imax
00868       real(kind=rKind)           :: mindepth
00869       real(kind=rKind)           :: delta1
00870       real(kind=rKind)           :: delta2
00871       !-------------------------------------------------------------------------------
00872       !                             IMPLEMENTATION
00873       !-------------------------------------------------------------------------------
00874 
00875       !
00876       imin = 1
00877       if (xmpi_istop) then
00878          !
00879          imin = 2
00880          !
00881       endif
00882 
00883       imax = s%nx
00884       if (xmpi_isbot) then
00885          !
00886          imax = s%nx-1
00887          !
00888       endif
00889 
00890       jmin = 1
00891       if (xmpi_isleft) then
00892          !
00893          jmin = 2
00894          !
00895       endif
00896 
00897       jmax = s%ny
00898       if (xmpi_isright) then
00899          !
00900          jmax = s%ny-1
00901          !
00902       endif
00903 
00904       if (s%ny > 0) then
00905          !
00906          ! 2DH Code
00907          !
00908          do j= jmin_uu , jmax_uu
00909             !
00910             do i = imin_uu, imax_uu ! Robert: was 1 , s%nx
00911                !
00912                ie  = min(i+1,imax+1)
00913                iee = min(i+2,imax+1)
00914                iw  = max(i-1,1)
00915                !
00916                mindepth = minval(s%zs(iw:iee,j))-maxval(s%zb(iw:iee,j))
00917                !
00918                if (mindepth>par%eps) then
00919                   !
00920                   if     (s%uu(i,j) >  par%umin .and. i > imin     ) then
00921                      !
00922                      delta1    =  (s%zs(ie,j)- s%zs(i,j ))/ s%dsu(i,1)
00923                      delta2    =  (s%zs(i,j) - s%zs(iw,j))/ s%dsu(i-1,1)
00924                      s%hu(i,j)  = s%hu(i,j) +  0.5d0*s%dsu(i,1)*minmod(delta1,delta2)
00925                      !
00926                   elseif (s%uu(i,j) < -par%umin .and. i < imax ) then
00927                      !
00928                      delta1    =  (s%zs(iee,j) - s%zs(ie,j)) / s%dsu(i+1,1)
00929                      delta2    =  (s%zs(ie ,j) - s%zs(i ,j)) / s%dsu(i,1)
00930                      s%hu(i,j)  = s%hu(i,j) - 0.5d0*s%dsu(i,1)*minmod(delta1,delta2)
00931                      !
00932                   endif
00933                   !
00934                endif
00935                !
00936             enddo
00937             !
00938          enddo
00939 
00940          do j= jmin_vv,jmax_vv ! Robert: was 1,s%ny
00941             !
00942             ie  = min(j+1,jmax+1)
00943             iee = min(j+2,jmax+1)
00944             iw  = max(j-1,1)
00945             !
00946             do i=imin_vv,imax_vv
00947                !
00948                mindepth = minval(s%zs(i,iw:iee))-maxval(s%zb(i,iw:iee))
00949                !
00950                if (mindepth>par%eps) then
00951                   !
00952                   if     (s%vv(i,j) >  par%umin .and. j>jmin     ) then
00953                      !
00954                      delta1    =  (s%zs(i,ie)- s%zs(i,j ))/ s%dnv(i,j)
00955                      delta2    =  (s%zs(i,j) - s%zs(i,iw))/ s%dnv(i,j-1)
00956                      s%hv(i,j)  = s%hv(i,j) +  0.5d0*s%dnv(i,j)*minmod(delta1,delta2)
00957                      !
00958                   elseif (s%vv(i,j) < -par%umin .and. j<jmax) then
00959                      !
00960                      delta1    =  (s%zs(i,iee) - s%zs(i,ie)) / s%dnv(i,j+1)
00961                      delta2    =  (s%zs(i ,ie) - s%zs(i ,j)) / s%dnv(i,j)
00962                      s%hv(i,j)  = s%hv(i,j) - 0.5d0*s%dnv(i,j)*minmod(delta1,delta2)
00963                      !
00964                   endif
00965                   !
00966                endif
00967                !
00968             enddo
00969          enddo
00970       else
00971          !
00972          ! 1DH Code
00973          !
00974          j= 1
00975          do i=imin_uu, imax_uu ! Robert: was 1,s%nx-1
00976             !
00977             ie  = min(i+1,imax+1)
00978             iee = min(i+2,imax+1)
00979             iw  = max(i-1,1)
00980             mindepth = minval(s%zs(iw:iee,j))-maxval(s%zb(iw:iee,j))
00981             !
00982             if (mindepth>par%eps) then
00983                !
00984                if     (s%uu(i,j) >  par%umin .and. i>imin    ) then
00985                   !
00986                   delta1    =  (s%zs(ie,j)- s%zs(i,j ))/ s%dsu(i,1)
00987                   delta2    =  (s%zs(i,j) - s%zs(iw,j))/ s%dsu(i-1,1)
00988                   s%hu(i,j)  = s%hu(i,j) +  0.5d0*s%dsu(i,1)*minmod(delta1,delta2)
00989                   !
00990                elseif (s%uu(i,j) < -par%umin .and. i<imax) then
00991                   !
00992                   delta1    =  (s%zs(iee,j) - s%zs(ie,j)) / s%dsu(i+1,1)
00993                   delta2    =  (s%zs(ie ,j) - s%zs(i ,j)) / s%dsu(i,1)
00994                   s%hu(i,j)  = s%hu(i,j) - 0.5d0*s%dsu(i,1)*minmod(delta1,delta2)
00995                endif
00996                !
00997             endif
00998             !
00999          enddo
01000          !
01001       endif
01002 
01003    end subroutine flow_secondorder_huhv
01004    !
01005    !==============================================================================
01006    real(kind=rKind) pure function minmod(delta1,delta2)
01007       !==============================================================================
01008       !
01009       ! DATE               AUTHOR               CHANGES
01010       !
01011       ! November 2010       Pieter Bart Smit     New Subroutine
01012       !
01013       !-------------------------------------------------------------------------------
01014       !                             DECLARATIONS
01015       !-------------------------------------------------------------------------------
01016 
01017       !
01018       !--------------------------        PURPOSE         ----------------------------
01019       !
01020       !   Limits succesive gradients using the TVD minmod limiter.
01021       !
01022       !--------------------------        METHOD          ----------------------------
01023       !
01024       ! - MINMOD LIMITER -
01025       !
01026       ! The minmod slope limiter essentiallycorrects the first order upwind
01027       ! estimate for hu/u/v with a second order upwind or central approximation.
01028       ! If the succesive gradients are opposite in sign the correction is set to zero to
01029       ! avoid unwanted oscillations.
01030       !
01031       ! Note: Declared as pure to explicitly denote that the function has no side effects.
01032       !       If this is not supported in the compiler the pure attribute can be safely removed.
01033       !
01034       ! ( see for instance Hirch [2001] for a better introduction to limiters. )
01035 
01036       !
01037       !--------------------------     DEPENDENCIES       ----------------------------
01038       !
01039       !                                 - NONE -
01040       !
01041       !--------------------------     ARGUMENTS          ----------------------------
01042       !
01043       real(kind=rKind),intent(in) :: delta1  ! first gradient
01044       real(kind=rKind),intent(in) :: delta2  ! secpond gradient
01045       !
01046       !--------------------------     LOCAL VARIABLES    ----------------------------
01047       !
01048       if (delta1*delta2 <= 0.0_rKind) then
01049          minmod = 0.0_rKind
01050          return
01051       endif
01052 
01053       if     (delta1 > 0.0_rKind) then
01054          minmod = min(delta1,delta2)
01055       elseif (delta1  < 0.0_rKind) then
01056          minmod = max(delta1,delta2)
01057       else
01058          minmod = 0.0_rKind
01059       endif
01060    end function minmod
01061 
01062 
01063 end module flow_secondorder_module
 All Classes Files Functions Variables Defines