XBeach
C:/repositories/XBeach/trunk/src/xbeachlibrary/boundaryconditions.F90
Go to the documentation of this file.
00001 module boundaryconditions
00002    use typesandkinds, only: slen
00003    use constants,     only: pi
00004    implicit none
00005    save
00006    private
00007    public flow_lat_bc, wave_bc, flow_bc, discharge_boundary_h, discharge_boundary_v
00008 contains
00009    subroutine wave_bc(sg,sl,par)
00010       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00011       ! Copyright (C) 2007 UNESCO-IHE, WL|Delft Hydraulics and Delft University !
00012       ! Dano Roelvink, Ap van Dongeren, Ad Reniers, Jamie Lescinski,            !
00013       ! Jaap van Thiel de Vries, Robert McCall                                  !
00014       !                                                                         !
00015       ! d.roelvink@unesco-ihe.org                                               !
00016       ! UNESCO-IHE Institute for Water Education                                !
00017       ! P.O. Box 3015                                                           !
00018       ! 2601 DA Delft                                                           !
00019       ! The Netherlands                                                         !
00020       !                                                                         !
00021       ! This library is free software; you can redistribute it and/or           !
00022       ! modify it under the terms of the GNU Lesser General Public              !
00023       ! License as published by the Free Software Foundation; either            !
00024       ! version 2.1 of the License, or (at your option) any later version.      !
00025       !                                                                         !
00026       ! This library is distributed in the hope that it will be useful,         !
00027       ! but WITHOUT ANY WARRANTY; without even the implied warranty of          !
00028       ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU        !
00029       ! Lesser General Public License for more details.                         !
00030       !                                                                         !
00031       ! You should have received a copy of the GNU Lesser General Public        !
00032       ! License along with this library; if not, write to the Free Software     !
00033       ! Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307     !
00034       ! USA                                                                     !
00035       !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00036       use params,                  only: parameters
00037       use spaceparamsdef
00038       use interp,                  only: linear_interp
00039       use wave_functions_module,   only: iteratedispersion, dispersion
00040       use xmpi_module             
00041       use logging_module,          only: writelog, report_file_read_error
00042       use nonh_module, only: nonh_init_wcoef
00043       use spectral_wave_bc_module, only: spectral_wave_bc
00044       use filefunctions,           only: create_new_fid
00045       use paramsconst
00046 #ifdef USEMPI
00047       use spaceparams,             only: space_distribute
00048 #endif
00049 
00050 
00051       implicit none
00052 
00053       type(spacepars), target                     :: sg, sl
00054       type(spacepars), pointer                    :: s
00055       type(parameters)                            :: par
00056 
00057       integer, save                               :: nt
00058       integer                                     :: i,new,reclen,wordsize
00059       integer, save                               :: old
00060       integer, save                               :: recpos, curline
00061       integer                                     :: j
00062       integer                                     :: itheta
00063       integer                                     :: E_idx
00064       integer                                     :: ier,ier2
00065       real*8                                      :: E1,ei,dum,Hm0, dum1, spreadpar, bcdur, dum2
00066       real*8, save                                :: dtbcfile,rt,bcendtime,bcstarttime
00067       real*8                                      :: em,tshifted,tnew
00068       real*8, save                                :: Emean,Llong
00069       real*8,dimension(:)     ,allocatable,save   :: e01,L0,L,Lest,kbw,wbw,tanhkhwb,kxmwt
00070       real*8,dimension(:)     ,allocatable,save   :: fac1,fac2
00071       real*8,dimension(:)     ,allocatable,save   :: tE,dataE,databi
00072       real*8,dimension(:,:)   ,allocatable,save   :: ht
00073       real*8,dimension(:,:)   ,allocatable,save   :: q1,q2,q
00074       real*8,dimension(:)     ,allocatable,save   :: wcrestpos
00075       real*8,dimension(:,:)   ,allocatable,save   :: ee1, ee2
00076       real*8,dimension(:,:)   ,allocatable,save   :: gq1,gq2,gq
00077       real*8,dimension(:,:)   ,allocatable,save   :: gee1, gee2
00078       character(len=1)                            :: bl
00079       character(slen),save                        :: ebcfname,qbcfname,nhbcfname,esbcfname
00080       real*8                                      :: E0,arms
00081       real*8,dimension(:),allocatable,save        :: dist,factor
00082       logical                                     :: startbcf
00083       logical                                     :: isSet_U,isSet_V,isSet_Z,isSet_W,isSet_dU,isSet_dV,isSet_Q
00084       real*8,dimension(:)     ,allocatable,save   :: uig,vig,zig,wig,duig,dvig
00085       real*8,dimension(:)     ,allocatable,save   :: tempu,tempv,tempdu,tempdv
00086 
00087       ! Initialize to false only once....
00088       logical, save                               :: bccreated = .false.
00089 
00090       s=>sl
00091 #ifndef USEMPI
00092       s=>sg
00093 #endif
00094 
00095       if (.not. allocated(fac1)) then
00096          allocate(ht      (2,s%ny+1))
00097          allocate(fac1    (s%nx))
00098          allocate(fac2    (s%nx))
00099          allocate(e01(1:s%ntheta))
00100          allocate(dist(1:s%ntheta))
00101          allocate(factor(1:s%ntheta))
00102          allocate(wcrestpos(s%nx+1))
00103          allocate(L(s%ny+1))
00104          allocate(L0(s%ny+1))
00105          allocate(Lest(s%ny+1))
00106          L0 = par%g*par%Trep**2/2/par%px
00107          L = L0
00108          allocate(kbw(s%ny+1))
00109          allocate(tanhkhwb(s%ny+1))
00110          allocate(kxmwt(s%ny+1))
00111          allocate(wbw(s%ny+1))
00112          wbw = 2*par%px/par%Trep
00113       endif
00114       !
00115       !  BLOCK I: GENERATE AND READ-IN WAVE BOUNDARY CONDITIONS
00116       !
00117       startbcf=.false.
00118       if(.not. bccreated ) then
00119          if (xmaster) then
00120             call writelog('ls','','Setting up boundary conditions')
00121          endif
00122          bccreated=.true.
00123          startbcf=.true.                     ! trigger read from bcf for instat 3,4,5,7
00124          bcendtime=huge(0.0d0)               ! initial assumption for instat 3,4,5,7
00125          s%newstatbc=1
00126          ! Part A) read-in / generate different wbctypes (and waveforms)
00127          ! 1) TS_1
00128          if (par%wbctype==WBCTYPE_TS_1) then
00129             if(xmaster) then
00130                open( unit=7, file='bc/gen.ezs')
00131             endif
00132             if (xmaster) then
00133 5              continue
00134                read(7,'(a)',iostat=ier)bl
00135                if (ier .ne. 0) then
00136                   call report_file_read_error('bc/gen.ezs')
00137                endif
00138                if(bl.eq.'*') goto 5
00139                read(7,*,iostat=ier)nt
00140                if (ier .ne. 0) then
00141                   call report_file_read_error('bc/gen.ezs')
00142                endif
00143             endif
00144 #ifdef USEMPI
00145             call xmpi_bcast(nt)
00146 #endif
00147             allocate(dataE  (nt))
00148             allocate(tE     (nt))
00149             do i=1,nt
00150                if(xmaster) then
00151                   read(7,*,iostat=ier) tE(i),dum,dataE(i)
00152                   if (ier .ne. 0) then
00153                      call report_file_read_error('bc/gen.ezs')
00154                   endif
00155                endif
00156 #ifdef USEMPI
00157                call xmpi_bcast(tE(i))
00158                call xmpi_bcast(dataE(i))
00159 #endif
00160             end do
00161             if (xmaster) then
00162                close(7)
00163             endif
00164             Emean=sum(dataE)/nt
00165             call dispersion(par,s,s%hh)
00166             ! 2) TS_2
00167          elseif (par%wbctype==WBCTYPE_TS_2) then
00168             if (xmaster) then
00169                open( unit=7, file='bc/gen.ezs')
00170 6              continue
00171                read(7,'(a)',iostat=ier)bl
00172                if (ier .ne. 0) then
00173                   call report_file_read_error('bc/gen.ezs')
00174                endif
00175                if(bl.eq.'*') goto 6
00176                read(7,*,iostat=ier)nt
00177                if (ier .ne. 0) then
00178                   call report_file_read_error('bc/gen.ezs')
00179                endif
00180             endif
00181 #ifdef USEMPI
00182             call xmpi_bcast(nt)
00183 #endif
00184             allocate(dataE  (nt))
00185             allocate(databi (nt))
00186             allocate(tE     (nt))
00187             do i=1,nt
00188                if(xmaster) then
00189                   read(7,*,iostat=ier) tE(i),databi(i),dataE(i)
00190                   if (ier .ne. 0) then
00191                      call report_file_read_error('bc/gen.ezs')
00192                   endif
00193                endif
00194 #ifdef USEMPI
00195                call xmpi_bcast(tE(i))
00196                call xmpi_bcast(databi(i))
00197                call xmpi_bcast(dataE(i))
00198 #endif
00199             end do
00200             if (xmaster) then
00201                close(7)
00202             endif
00203             Emean=sum(dataE)/nt
00204             call dispersion(par,s,s%hh)
00205             ! 3) jons_table in combination with stationary
00206          elseif (par%wbctype==WBCTYPE_JONS_TABLE .and. par%wavemodel==WAVEMODEL_STATIONARY) then
00207             if (xmaster) then
00208                open( unit=7, file=par%bcfile)
00209                read(7,*,iostat=ier) Hm0, par%Trep,par%dir0, dum1, spreadpar, bcendtime, dum2
00210                if (ier .ne. 0) then
00211                   call report_file_read_error(par%bcfile)
00212                endif
00213                par%Hrms = Hm0/sqrt(2.d0)
00214                par%m = int(2*spreadpar)
00215                if (par%morfacopt==1) bcendtime=bcendtime/max(par%morfac,1.d0)
00216                s%theta0=(1.5d0*par%px)-par%dir0*atan(1.d0)/45.d0
00217                do while(s%theta0<-par%px)
00218                   s%theta0=s%theta0+2.d0*par%px
00219                enddo
00220                do while(s%theta0>par%px)
00221                   s%theta0=s%theta0-2.d0*par%px
00222                enddo
00223             endif
00224             s%newstatbc=1
00225 #ifdef USEMPI
00226             call xmpi_bcast(bcendtime)
00227             call xmpi_bcast(par%Hrms)
00228             call xmpi_bcast(par%Trep)
00229             call xmpi_bcast(par%m)
00230             call xmpi_bcast(s%theta0)
00231 #endif
00232             do itheta=1,s%ntheta
00233                s%sigt(:,:,itheta) = 2.d0*par%px/par%Trep
00234             end do
00235             s%sigm = sum(s%sigt,3)/s%ntheta
00236             call dispersion(par,s,s%hh)
00237 
00238             ! 4)  jons_table in combination with surfbeat or nonh
00239          elseif ((par%wbctype==WBCTYPE_PARAMETRIC .or. par%wbctype==WBCTYPE_JONS_TABLE) .and. &
00240          (par%wavemodel/=WAVEMODEL_STATIONARY .and. xmaster)) then
00241             call spectral_wave_bc(sg,par,curline)
00242             ! 5) SWAN
00243          elseif (par%wbctype==WBCTYPE_SWAN.and.xmaster) then
00244             call spectral_wave_bc(sg,par,curline)
00245             ! 6) vardens
00246          elseif (par%wbctype==WBCTYPE_VARDENS.and.xmaster) then
00247             call spectral_wave_bc(sg,par,curline)
00248             ! 7) reuse
00249          elseif (par%wbctype==WBCTYPE_REUSE.and.xmaster) then
00250             curline = 1
00251             ! 8) ts_nonh
00252          elseif (par%wbctype==WBCTYPE_TS_NONH) then
00253             if (.not. allocated(uig)) then
00254                if (xmaster) then
00255                   allocate(uig(sg%ny+1))
00256                   allocate(vig(sg%ny+1))
00257                   allocate(zig(sg%ny+1))
00258                   allocate(wig(sg%ny+1))
00259                   allocate(duig(sg%ny+1))
00260                   allocate(dvig(sg%ny+1))
00261                else  ! only need valid address for MPI-distribution
00262                   allocate(uig(1))
00263                   allocate(vig(1))
00264                   allocate(zig(1))
00265                   allocate(wig(1))
00266                   allocate(duig(1))
00267                   allocate(dvig(1))
00268                endif
00269             endif
00270             if (xmaster) then
00271                call velocity_Boundary('boun_U.bcf',uig,vig,zig,wig,duig,dvig,sg%ny,par%t, &
00272                isSet_U,isSet_V,isSet_Z,isSet_W,isSet_dU,isSet_dV,isSet_Q)
00273             endif
00274          endif  ! done with the different wbctypes
00275          !
00276          ! Part B) Directional distribution for non-spectral wbctypes
00277          if (par%wbctype==WBCTYPE_PARAMS .or. par%wbctype==WBCTYPE_TS_1 .or. par%wbctype==WBCTYPE_TS_2 .or. &
00278          (par%wbctype==WBCTYPE_JONS_TABLE .and. par%wavemodel==WAVEMODEL_STATIONARY)  ) then
00279             dist=(cos(s%theta-s%theta0))**par%m
00280             do i=1,s%ntheta
00281                if(cos(s%theta(i)-s%theta0)<0.d0) then
00282                   dist(i)=0.0d0
00283                end if
00284             end do
00285             if (par%wbctype==WBCTYPE_TS_1 .or. par%wbctype==WBCTYPE_TS_2) then
00286                par%Hrms=sqrt(8*Emean/(par%rho*par%g))
00287             endif
00288             E0=par%rhog8*par%Hrms**2
00289             ! Energy density distribution
00290             if (sum(dist)>0.d0) then
00291                factor = (dist/sum(dist))/s%dtheta
00292             else
00293                factor=0.d0
00294             endif
00295             e01    = factor*E0;
00296             e01    = max(e01,0.0d0);
00297             Llong  = par%Tlong*s%cg(1,1)
00298          endif
00299          if (xmaster) then
00300             call writelog('sl','','Boundary conditions complete, starting computation')
00301          endif
00302       end if ! if bc was not created
00303       !
00304       ! BLOCK II: Recalculate bcf-file
00305       !
00306       if (par%t .ge. bcendtime) then
00307          ! Go over the different wbctypes (and wavemodel)
00308          ! 1) jons_table in combination with stationary
00309          if (par%wbctype==WBCTYPE_JONS_TABLE .and. par%wavemodel==WAVEMODEL_STATIONARY) then
00310             if (xmaster) then
00311                call writelog('ls','','Reading new wave conditions')
00312                ! read new wave conditions until bcendtime exceeds current time step
00313                ! necessary in case of external time management
00314                do while (par%t .ge. bcendtime)
00315                   read(7,*,iostat=ier) Hm0, par%Trep,par%dir0, dum1, spreadpar, bcdur, dum2
00316                   if (ier .ne. 0) then
00317                      call report_file_read_error(par%bcfile)
00318                   endif
00319                   par%Hrms = Hm0/sqrt(2.d0)
00320                   ! set taper time to 1 second for new conditions (likewise in waveparams)
00321                   par%taper = 0.d0
00322                   par%m = int(2*spreadpar)
00323                   if (par%morfacopt==1) then
00324                      bcendtime=bcendtime+bcdur/max(par%morfac,1.d0)
00325                   else
00326                      bcendtime=bcendtime+bcdur
00327                   endif
00328                   s%theta0=(1.5d0*par%px)-par%dir0*atan(1.d0)/45.d0
00329                   ! Make shore theta0 is also set between -px and px for new wave conditions
00330                   do while(s%theta0<-par%px)
00331                      s%theta0=s%theta0+2.d0*par%px
00332                   enddo
00333                   do while(s%theta0>par%px)
00334                      s%theta0=s%theta0-2.d0*par%px
00335                   enddo
00336                enddo
00337             endif
00338             s%newstatbc=1
00339 #ifdef USEMPI
00340             call xmpi_bcast(bcendtime)
00341             call xmpi_bcast(par%Hrms)
00342             call xmpi_bcast(par%Trep)
00343             call xmpi_bcast(par%m)
00344             call xmpi_bcast(s%theta0)
00345 #endif
00346             do itheta=1,s%ntheta
00347                s%sigt(:,:,itheta) = 2*par%px/par%Trep
00348             end do
00349             s%sigm = sum(s%sigt,3)/s%ntheta
00350             call dispersion(par,s,s%hh)
00351             ! Directional distribution
00352             dist=(cos(s%theta-s%theta0))**par%m
00353             do i=1,s%ntheta
00354                if(cos(s%theta(i)-s%theta0)<0.d0) then
00355                   dist(i)=0
00356                end if
00357             end do
00358             E0=par%rhog8*par%Hrms**2
00359             ! Energy density distribution
00360             if (sum(dist)>0.d0) then
00361                factor = (dist/sum(dist))/s%dtheta
00362             else
00363                factor=0.d0
00364             endif
00365             e01    = factor*E0;
00366             e01    = max(e01,0.0d0);
00367             ! 2) JONSWAP (table)
00368          elseif ((par%wbctype==WBCTYPE_PARAMETRIC .or. par%wbctype==WBCTYPE_JONS_TABLE) .and. &
00369          (par%wavemodel/=WAVEMODEL_STATIONARY .and. xmaster)) then
00370             close(71)
00371             close(72)
00372             call spectral_wave_bc(sg,par,curline)
00373             startbcf=.true.
00374             ! 3) SWAN
00375          elseif (par%wbctype==WBCTYPE_SWAN.and.xmaster) then
00376             close(71)
00377             close(72)
00378             call spectral_wave_bc(sg,par,curline)
00379             startbcf=.true.
00380             ! 4) vardens
00381          elseif (par%wbctype==WBCTYPE_VARDENS.and.xmaster) then
00382             close(71)
00383             close(72)
00384             call spectral_wave_bc(sg,par,curline)
00385             startbcf=.true.
00386             ! 5) reuse
00387          elseif (par%wbctype==WBCTYPE_REUSE.and.xmaster) then
00388             close(71)
00389             close(72)
00390             startbcf=.true.
00391             if (par%t <= (par%tstop-par%dt)) then
00392                ! this is not compatible with external time management
00393                curline = curline + 1
00394             end if
00395          end if ! go over the different wbctypes
00396 #ifdef USEMPI
00397          call xmpi_bcast(startbcf)
00398 #endif
00399       end if ! done recalculating bcf-file
00400       !
00401       ! BLOCK III: COMPUTE WAVE BOUNDARY CONDITIONS CURRENT TIMESTEP
00402       !
00403       ! Part A) Stationary: go over the different waveforms
00404       if (par%wavemodel==WAVEMODEL_STATIONARY) then
00405          ! Go over all excepted wbctypes (all the same)
00406          if (par%wbctype == WBCTYPE_PARAMS .or. par%wbctype == WBCTYPE_JONS_TABLE) then
00407             ! Dano reset waves for new wave condition in stationary case, to avoid 'leftovers'
00408             if (s%newstatbc==1) s%ee=0.d0
00409             if(par%taper>tiny(0.d0)) then
00410                do j=1,s%ny+1
00411                   s%ee(1,j,:) = e01*min(par%t/par%taper,1.0d0)
00412                enddo
00413             else
00414                do j=1,s%ny+1
00415                   s%ee(1,j,:) = e01
00416                enddo
00417             endif
00418             s%bi(1) = 0.d0
00419             s%ui(1,:)   = 0.0d0
00420          else
00421          endif   ! Go over the different wbctypes for wavemodel = stationary
00422          !
00423          ! Part B) Surfbeat: go over the different waveforms
00424       elseif (par%wavemodel == WAVEMODEL_SURFBEAT) then
00425          ! 1) Bichromatic waves
00426          if (    (par%wbctype == WBCTYPE_PARAMS) .and. (par%Tlong /= -123) .and. xmpi_istop   ) then
00427             do j=1,s%ny+1
00428                s%ee(1,j,:)=e01*0.5d0 * &
00429                (1.d0+cos(2*par%px*(par%t/par%Tlong-( sin(s%theta0)*(s%yz(1,j)-s%yz(1,1)) & !jaap : -sum(s%alfaz(1,1:j))/j
00430                +cos(s%theta0)*(s%xz(1,j)-s%xz(1,1)) )/Llong))) * & !jaap: -sum(s%alfaz(1,1:j))/j
00431                min(par%t/par%taper,1.d0)
00432                em = (sum(0.5d0*e01))*s%dtheta *min(par%t/par%taper,1.d0)
00433                ei =  sum(s%ee(1,j,1:s%ntheta))*s%dtheta
00434                s%bi(1) = -(2*s%cg(1,j)/s%c(1,j)-0.5d0)*(em-ei)/(s%cg(1,j)**2-par%g*s%hh(1,j))/par%rho
00435                ht=s%zs0(1:2,:)-s%zb(1:2,:)
00436                s%ui(1,j) = s%cg(1,j)*s%bi(1)/ht(1,j)*cos(s%theta0-s%alfaz(1,j))
00437             end do
00438             ! 2) TS_1: bound long wave is calculate by the bound long wave theory of LG & Steward (1964)
00439          elseif (par%wbctype==WBCTYPE_TS_1 .and. xmpi_istop) then
00440             do j=1,s%ny+1
00441                if (abs(s%theta0-sum(s%alfaz(1,1:j))/j)<1e-3) then
00442                   call linear_interp(tE,dataE,nt,par%t,E1,E_idx)
00443                else
00444                   tshifted = max(par%t-(s%yz(1,j)-s%yz(1,1))*sin(s%theta0)/s%cg(1,1) & !-sum(s%alfaz(1,1:j))/j
00445                   +(s%xz(1,j)-s%xz(1,1))*cos(s%theta0)/s%cg(1,1),0.d0) !-sum(s%alfaz(1,1:j))/j
00446                   call linear_interp(tE,dataE,nt,tshifted,E1,E_idx)
00447                endif
00448                s%ee(1,j,:)=e01*E1/max(Emean,0.000001d0)*min(par%t/par%taper,1.d0)
00449                em = Emean *min(par%t/par%taper,1.d0)
00450                ei = sum(s%ee(1,j,:))*s%dtheta
00451                s%bi(1) = -(2*s%cg(1,j)/s%c(1,j)-0.5d0)*(em-ei)/(s%cg(1,j)**2-par%g*s%hh(1,j))/par%rho
00452                ht=s%zs0(1:2,:)-s%zb(1:2,:)
00453                s%ui(1,j) = s%cg(1,j)*s%bi(1)/ht(1,j)*cos(s%theta0-s%alfaz(1,j))
00454             end do
00455             ! 3) TS_2: bound long wave is specificed by the user
00456          elseif (par%wbctype==WBCTYPE_TS_2 .and. xmpi_istop) then
00457             ht=s%zs0(1:2,:)-s%zb(1:2,:)
00458             do j=1,s%ny+1
00459                if (abs(s%theta0-sum(s%alfaz(1,1:j))/j)<1e-3) then
00460                   call linear_interp(tE,dataE,nt,par%t,E1,E_idx)
00461                   call linear_interp(tE,databi,nt,par%t,s%bi(1),E_idx)
00462                else
00463                   tshifted = max(par%t-(s%yz(1,j)-s%yz(1,1))*sin(s%theta0)/s%cg(1,1) & !-sum(s%alfaz(1,1:j))/j
00464                   +(s%xz(1,j)-s%xz(1,1))*cos(s%theta0)/s%cg(1,1),0.d0) !-sum(s%alfaz(1,1:j))/j
00465                   call linear_interp(tE,dataE,nt,tshifted,E1,E_idx)
00466                   call linear_interp(tE,databi,nt,tshifted,s%bi(1),E_idx)
00467                endif
00468                s%ee(1,j,:)=e01*E1/max(Emean,0.000001d0)*min(par%t/par%taper,1.d0)
00469                if (par%freewave==1) then
00470                   s%ui(1,j) = sqrt(par%g/ht(1,j))*s%bi(1)
00471                else
00472                   s%ui(1,j) = s%cg(1,j)*s%bi(1)/ht(1,j)*cos(s%theta0-s%alfaz(1,j))*min(par%t/par%taper,1.d0)
00473                endif
00474             end do
00475             ! 4) go over the different wbctypes (spectral)
00476          else
00477             if ((par%wbctype==WBCTYPE_PARAMETRIC) .or. (par%wbctype==WBCTYPE_JONS_TABLE) .or. &
00478             (par%wbctype==WBCTYPE_SWAN) .or. (par%wbctype==WBCTYPE_VARDENS) .or. (par%wbctype==WBCTYPE_REUSE)) then
00479                ! open file if first time
00480                if (startbcf) then
00481                   if(xmaster) then
00482                      open(53,file='ebcflist.bcf',form='formatted',position='rewind')
00483                      open(54,file='qbcflist.bcf',form='formatted',position='rewind')
00484                      if(par%single_dir==1 .and. par%wbctype==WBCTYPE_REUSE) then
00485                         open(55,file='esbcflist.bcf',form='formatted',position='rewind')
00486                      endif
00487                   endif
00488                   if (xmaster) then
00489                      do i=1,curline
00490                         read(53,*,iostat=ier)bcendtime,rt,dtbcfile,par%Trep,s%theta0,ebcfname
00491                         if (ier .ne. 0) then
00492                            call report_file_read_error('ebcflist.bcf')
00493                         endif
00494                         read(54,*,iostat=ier)bcendtime,rt,dtbcfile,par%Trep,s%theta0,qbcfname
00495                         if (ier .ne. 0) then
00496                            call report_file_read_error('qbcflist.bcf')
00497                         endif
00498                         if(par%single_dir==1 .and. par%wbctype==WBCTYPE_REUSE) then
00499                            read(55,*,iostat=ier)bcendtime,rt,dtbcfile,par%Trep,s%theta0,esbcfname
00500                            if (ier .ne. 0) then
00501                               call report_file_read_error('esbcflist.bcf')
00502                            endif
00503                         endif
00504                      enddo  ! wwvv strange
00505                      if(par%single_dir==1 .and. par%wbctype==WBCTYPE_REUSE) then
00506                         inquire(iolength=wordsize) 1.d0
00507                         reclen=wordsize*(sg%ny+1)*(sg%ntheta_s)
00508                         open(73,file=esbcfname,status='old',form='unformatted',access='direct',recl=reclen)
00509                         read(73,rec=1,iostat=ier)sg%ee_s(1,:,:)
00510                         if (ier .ne. 0) then
00511                            call report_file_read_error(esbcfname)
00512                         endif
00513                         close(73)
00514                      endif
00515                   endif
00516 #ifdef USEMPI
00517                   call xmpi_bcast(bcendtime)
00518                   call xmpi_bcast(rt)
00519                   call xmpi_bcast(dtbcfile)
00520                   call xmpi_bcast(par%Trep)
00521                   call xmpi_bcast(s%theta0)
00522                   call xmpi_bcast(ebcfname)
00523                   if (par%single_dir==1) then
00524                      call space_distribute("y",sl,sg%ee_s(1,:,:),s%ee_s(1,:,:))
00525                   endif
00526 #else
00527                   if (par%single_dir==1) then
00528                      s%ee_s=sg%ee_s
00529                   endif
00530 #endif
00531                   if (xmaster) then
00532                      close(53)
00533                      close(54)
00534                      if(par%single_dir==1 .and. par%wbctype==WBCTYPE_REUSE) then
00535                         close(55)
00536                      endif
00537                   endif
00538                   ! Robert and Jaap : Initialize for new wave conditions
00539                   do itheta=1,s%ntheta
00540                      s%sigt(:,:,itheta) = 2*par%px/par%Trep
00541                   end do
00542                   s%sigm = sum(s%sigt,3)/s%ntheta
00543                   call dispersion(par,s,s%hh)
00544                   ! End initialize
00545                   if (xmaster) then
00546                      inquire(iolength=wordsize) 1.d0
00547                      reclen=wordsize*(sg%ny+1)*(sg%ntheta)
00548                      open(71,file=ebcfname,status='old',form='unformatted',access='direct',recl=reclen)
00549                      reclen=wordsize*((sg%ny+1)*4)
00550                      open(72,file=qbcfname,status='old',form='unformatted',access='direct',recl=reclen)
00551                   endif
00552                   ! wwvv note that we need the global value of ny here
00553                   ! masterprocess reads and distributes
00554                   if (xmaster) then
00555                      if (.not. allocated(gq1) ) then
00556                         allocate(gq1(sg%ny+1,4),gq2(sg%ny+1,4),gq(sg%ny+1,4))
00557                         allocate(gee1(sg%ny+1,s%ntheta),gee2(sg%ny+1,s%ntheta))
00558                      endif
00559                   else
00560                      if (.not. allocated(gq1) ) then ! to get valid addresses for
00561                         ! gq1, gq2, gq, gee1, gee2
00562                         allocate(gq1(1,4),gq2(1,4),gq(1,4))
00563                         allocate(gee1(1,s%ntheta),gee2(1,s%ntheta))
00564                      endif
00565                   endif
00566                   if (.not. allocated(q1) ) then
00567                      allocate(q1(s%ny+1,4),q2(s%ny+1,4),q(s%ny+1,4))
00568                      allocate(ee1(s%ny+1,s%ntheta),ee2(s%ny+1,s%ntheta))
00569                   end if
00570                   if (xmaster) then
00571                      read(71,rec=1,iostat=ier)gee1       ! Earlier in time
00572                      read(71,rec=2,iostat=ier2)gee2       ! Later in time
00573                      if (ier+ier2 .ne. 0) then
00574                         call report_file_read_error(ebcfname)
00575                      endif
00576                      read(72,rec=1,iostat=ier)gq1        ! Earlier in time
00577                      read(72,rec=2,iostat=ier2)gq2        ! Later in time
00578                      if (ier+ier2 .ne. 0) then
00579                         call report_file_read_error(qbcfname)
00580                      endif
00581                   endif
00582 #ifdef USEMPI
00583                   call space_distribute("y",sl,gee1,ee1)
00584                   call space_distribute("y",sl,gee2,ee2)
00585                   call space_distribute("y",sl,gq1,q1)
00586                   call space_distribute("y",sl,gq2,q2)
00587 #else
00588                   ee1=gee1
00589                   ee2=gee2
00590                   q1=gq1
00591                   q2=gq2
00592 #endif
00593                   old=floor((par%t/dtbcfile)+1)
00594                   recpos=1
00595                end if
00596                new=floor((par%t/dtbcfile)+1)
00597                ! Check for next level in boundary condition file
00598                if (new/=old) then
00599                   recpos=recpos+(new-old)
00600                   ! Check for how many bcfile steps are jumped
00601                   if (new-old>1) then  ! Many steps further in the bc file
00602                      if(xmaster) then
00603                         read(72,rec=recpos+1,iostat=ier)gq2
00604                         if (ier .ne. 0) then
00605                            call report_file_read_error(qbcfname)
00606                         endif
00607                         read(71,rec=recpos+1,iostat=ier)gee2
00608                         if (ier .ne. 0) then
00609                            call report_file_read_error(ebcfname)
00610                         endif
00611                         read(72,rec=recpos,iostat=ier)gq1
00612                         if (ier .ne. 0) then
00613                            call report_file_read_error(qbcfname)
00614                         endif
00615                         read(71,rec=recpos,iostat=ier)gee1
00616                         if (ier .ne. 0) then
00617                            call report_file_read_error(ebcfname)
00618                         endif
00619                      endif
00620 #ifdef USEMPI
00621                      call space_distribute("y",sl,gee2,ee2)
00622                      call space_distribute("y",sl,gq2,q2)
00623                      call space_distribute("y",sl,gee1,ee1)
00624                      call space_distribute("y",sl,gq1,q1)
00625 #else
00626                      ee1=gee1
00627                      ee2=gee2
00628                      q1=gq2
00629                      q2=gq2
00630 #endif
00631                   else  ! Only one step further in the bc file
00632                      ee1=ee2
00633                      q1=q2
00634                      if(xmaster) then
00635                         read(72,rec=recpos+1,iostat=ier)gq2
00636                         if (ier .ne. 0) then
00637                            call report_file_read_error(qbcfname)
00638                         endif
00639                         read(71,rec=recpos+1,iostat=ier)gee2
00640                         if (ier .ne. 0) then
00641                            call report_file_read_error(ebcfname)
00642                         endif
00643                      endif
00644 #ifdef USEMPI
00645                      call space_distribute("y",sl,gee2,ee2)
00646                      call space_distribute("y",sl,gq2,q2)
00647 #else
00648                      ee2=gee2
00649                      q2=gq2
00650 #endif
00651                   endif
00652                   old=new
00653                end if
00654                ht=s%zs0(1:2,:)-s%zb(1:2,:)
00655                tnew = dble(new)*dtbcfile
00656                if (xmpi_istop) s%ee(1,:,:) = (dtbcfile-(tnew-par%t))/dtbcfile*ee2 + & !Jaap
00657                (tnew-par%t)/dtbcfile*ee1
00658                q = (dtbcfile-(tnew-par%t))/dtbcfile*q2 + &          !Jaap
00659                (tnew-par%t)/dtbcfile*q1
00660                ! be aware: ui and vi are defined w.r.t. the grid, not w.r.t. the coordinate system!
00661                s%ui(1,:) = (q(:,1)*dcos(s%alfau(1,:)) + q(:,2)*dsin(s%alfau(1,:)))/ht(1,:)*min(par%t/par%taper,1.0d0)
00662                s%vi(1,:) = (-q(:,1)*dsin(s%alfau(1,:)) + q(:,2)*dcos(s%alfau(1,:)))/ht(1,:)*min(par%t/par%taper,1.0d0)
00663                if (xmpi_istop) s%ee(1,:,:)=s%ee(1,:,:)*min(par%t/par%taper,1.0d0)
00664             else
00665             endif
00666          endif ! Go over the different wbctypes for surfbeat
00667          ! Part C) Nonh: go over the different waveforms
00668       elseif (par%wavemodel == WAVEMODEL_NONH) then
00669          ! 1) monochromatic waves
00670          if (par%wbctype==WBCTYPE_PARAMS) then
00671             wbw = 2*par%px/par%Trep
00672             do j=1,s%ny+1
00673                Lest(j) = L(j)
00674                L(j) = iteratedispersion(L0(j),Lest(j),par%px,s%hh(1,j))
00675             enddo
00676             kbw = 2*par%px/L
00677             arms = par%Hrms/2
00678             if(par%order==1) then
00679                s%zi(1,:) = arms*dsin(wbw*par%t-kbw*( dsin(s%theta0)*(s%yz(1,:)-s%yz(1,1)) &
00680                +dcos(s%theta0)*(s%xz(1,:)-s%xz(1,1)) &
00681                ) &
00682                )
00683                s%ui(1,:) = 1.d0/s%hh(1,:)*wbw*arms/sinh(kbw*s%hh(1,:)) * &
00684                dsin(wbw*par%t &
00685                -kbw*( dsin(s%theta0)*(s%yz(1,:)-s%yz(1,1)) &
00686                +dcos(s%theta0)*(s%xz(1,:)-s%xz(1,1)) &
00687                ) &
00688                ) * &
00689                1.d0/kbw*sinh(kbw*s%hh(1,:)) *dcos(s%theta0-s%alfaz(1,:))
00690             elseif(par%order==2) then
00691                ! 2nd order Stokes wave: To do more extensive testing
00692                tanhkhwb = tanh(kbw*s%hh(1,:))
00693                kxmwt = kbw*(dsin(s%theta0)*(s%yz(1,:)-s%yz(1,1))+dcos(s%theta0)*(s%xz(1,:)-s%xz(1,1))) - wbw*par%t
00694                s%zi(1,:) = arms*(dcos(kxmwt) + kbw*arms*(3-tanhkhwb**2)/(4*tanhkhwb**3)*dcos(2*kxmwt))
00695                s%ui(1,:) = (wbw/kbw)/s%hh(1,:)*s%zi(1,:) *dcos(s%theta0-s%alfaz(1,:))
00696             elseif(par%order==3) then
00697                ! 3rd order Stokes wave: only deep water
00698                !s%zi(1,:) = arms*(dcos(wbw *par%t) + 0.5d0*kbw*arms*dcos(2*wbw*par%t) + 0.375d0*(kbw*arms)**2*dcos(3*wbw*par%t))
00699                !s%ui(1,:) = (wbw/kbw)/s%hh(1,:)*s%zi(1,:)
00700             endif
00701             ! 2) spectral
00702          elseif ((par%wbctype==WBCTYPE_PARAMETRIC) .or. (par%wbctype==WBCTYPE_JONS_TABLE) .or. &
00703          (par%wbctype==WBCTYPE_SWAN) .or. (par%wbctype==WBCTYPE_VARDENS) .or. (par%wbctype==WBCTYPE_REUSE)) then
00704             if (startbcf) then
00705                if(xmaster) then
00706                   open(53,file='nhbcflist.bcf',form='formatted',position='rewind')
00707                   do i=1,curline
00708                      read(53,*,iostat=ier)bcstarttime,bcendtime,par%Trep,nhbcfname
00709                      if (ier .ne. 0) then
00710                         call report_file_read_error('nhbcflist.bcf')
00711                      endif
00712                   enddo
00713                   close(53)
00714                endif
00715                if (.not. allocated(uig)) then
00716                   if (xmaster) then
00717                      allocate(uig(sg%ny+1))
00718                      allocate(vig(sg%ny+1))
00719                      allocate(zig(sg%ny+1))
00720                      allocate(wig(sg%ny+1))
00721                      allocate(duig(sg%ny+1))
00722                      allocate(dvig(sg%ny+1))
00723                   else  ! only need valid address for MPI-distribution
00724                      allocate(uig(1))
00725                      allocate(vig(1))
00726                      allocate(zig(1))
00727                      allocate(wig(1))
00728                      allocate(duig(1))
00729                      allocate(dvig(1))
00730                   endif
00731                endif
00732                if (xmaster) then
00733                   ! Robert: optimise?
00734                   if (trim(nhbcfname)=='nh_reuse.bcf') then
00735                      ! Reuse time series will start at t=0, so we need to add the offset time to
00736                      ! the time vector in the boundary condition file using the optional bcst variable
00737                      call velocity_Boundary(nhbcfname,uig,vig,zig,wig,duig,dvig,sg%ny,par%t, &
00738                      isSet_U,isSet_V,isSet_Z,isSet_W,isSet_dU,isSet_dV,isSet_Q, &
00739                      force_init=.true.,bcst=bcstarttime)
00740                   else
00741                      ! If individual spectra are read, then the time vector in the boundary condition
00742                      ! file will already be corrected for the start of the spectrum condition. No need
00743                      ! to add the optional bcst variable
00744                      call velocity_Boundary(nhbcfname,uig,vig,zig,wig,duig,dvig,sg%ny,par%t, &
00745                      isSet_U,isSet_V,isSet_Z,isSet_W,isSet_dU,isSet_dV,isSet_Q, &
00746                      force_init=.true.)
00747                   endif
00748                endif
00749 #ifdef USEMPI
00750                call space_distribute("y",sl,uig,s%ui(1,:))
00751                call space_distribute("y",sl,vig,s%vi(1,:))
00752                call space_distribute("y",sl,zig,s%zi(1,:))
00753                call space_distribute("y",sl,wig,s%wi(1,:))
00754                call space_distribute("y",sl,duig,s%dui(1,:))
00755                call space_distribute("y",sl,dvig,s%dvi(1,:))
00756                call xmpi_bcast(isSet_U)
00757                call xmpi_bcast(isSet_V)
00758                call xmpi_bcast(isSet_Z)
00759                call xmpi_bcast(isSet_W)
00760                call xmpi_bcast(isSet_dU)
00761                call xmpi_bcast(isSet_dV)
00762                call xmpi_bcast(bcendtime)
00763 #else
00764                s%ui(1,:) = uig
00765                s%vi(1,:) = vig
00766                s%zi(1,:) = zig
00767                s%wi(1,:) = wig
00768                s%dui(1,:) = duig
00769                s%dvi(1,:) = dvig
00770 #endif
00771                if (.not. isSet_U) s%ui(1,:) = 0.d0
00772                if (.not. isSet_Z) s%zi(1,:) = s%zs(2,:)
00773                if (.not. isSet_W) s%wi(1,:) = s%ws(2,:)
00774                if (.not. isSet_V) then 
00775                   s%vi(1,:) = 0.d0
00776                   s%isSet_Vbc = 0
00777                else
00778                   s%isSet_Vbc = 1
00779                endif
00780                if (par%nonhq3d == 1 .and. par%nhlay > 0.0d0) then
00781                   ! Only if the reduced 2-layer model is initiated (P.B. Smit)
00782                   if (.not. isSet_dU) s%dUi(1,:) = 0.d0
00783                   if (.not. isSet_dV) s%dVi(1,:) = 0.d0
00784                endif
00785                call nonh_init_wcoef(s,par)
00786             else
00787                if (xmaster) then
00788                   if (trim(nhbcfname)=='nh_reuse.bcf') then
00789                      ! Reuse time series will start at t=0, so we need to add the offset time to
00790                      ! the time vector in the boundary condition file using the optional bcst variable
00791                      call velocity_Boundary(nhbcfname,uig,vig,zig,wig,duig,dvig,sg%ny,par%t,&
00792                      isSet_U,isSet_V,isSet_Z,isSet_W,isSet_dU,isSet_dV,isSet_Q, &
00793                      bcst=bcstarttime)
00794                   else
00795                      ! If individual spectra are read, then the time vector in the boundary condition
00796                      ! file will already be corrected for the start of the spectrum condition. No need
00797                      ! to add the optional bcst variable
00798                      call velocity_Boundary(nhbcfname,uig,vig,zig,wig,duig,dvig,sg%ny,par%t, &
00799                      isSet_U,isSet_V,isSet_Z,isSet_W,isSet_dU,isSet_dV,isSet_Q)
00800                   endif
00801                endif
00802 #ifdef USEMPI
00803                call space_distribute("y",sl,uig,s%ui(1,:))
00804                call space_distribute("y",sl,vig,s%vi(1,:))
00805                call space_distribute("y",sl,zig,s%zi(1,:))
00806                call space_distribute("y",sl,wig,s%wi(1,:))
00807                call space_distribute("y",sl,duig,s%dui(1,:))
00808                call space_distribute("y",sl,dvig,s%dvi(1,:))
00809                call xmpi_bcast(isSet_U)
00810                call xmpi_bcast(isSet_V)
00811                call xmpi_bcast(isSet_Z)
00812                call xmpi_bcast(isSet_W)
00813                call xmpi_bcast(isSet_dU)
00814                call xmpi_bcast(isSet_dV)
00815 #else
00816                s%dui(1,:) = duig
00817                s%dvi(1,:) = dvig
00818                s%ui(1,:) = uig
00819                s%vi(1,:) = vig
00820                s%zi(1,:) = zig
00821                s%wi(1,:) = wig
00822 #endif
00823                if (.not. isSet_U) s%ui(1,:) = 0.d0
00824                if (.not. isSet_Z) s%zi(1,:) = s%zs(2,:)
00825                if (.not. isSet_W) s%wi(1,:) = s%ws(2,:)
00826                if (.not. isSet_V) then 
00827                   s%vi(1,:) = 0.d0
00828                   s%isSet_Vbc = 0
00829                else
00830                   s%isSet_Vbc = 1
00831                endif
00832                if (par%nonhq3d == 1 .and. par%nhlay > 0.0d0) then
00833                   ! Only if the reduced 2-layer model is initiated (P.B. Smit)
00834                   if (.not. isSet_dU) s%dUi(1,:) = 0.d0
00835                   if (.not. isSet_dV) s%dVi(1,:) = 0.d0
00836                   !
00837                endif
00838             endif
00839             ! be aware: ui and vi are defined w.r.t. the grid, not w.r.t. the coordinate system!
00840             if (.not. allocated(tempu)) then
00841                ! allocate to local size grid
00842                allocate(tempu(s%ny+1))
00843                allocate(tempv(s%ny+1))
00844                allocate(tempdv(s%ny+1))
00845                allocate(tempdu(s%ny+1))
00846             endif
00847             tempu = s%ui(1,:)
00848             tempv = s%vi(1,:)
00849             tempdu = s%dUi(1,:)
00850             tempdv = s%dVi(1,:)
00851             ! rotate to grid directions
00852             s%ui(1,:) = tempu*dcos(s%alfau(1,:)) + tempv*dsin(s%alfau(1,:))
00853             s%vi(1,:) = -tempu*dsin(s%alfau(1,:)) + tempv*dcos(s%alfau(1,:))
00854             s%dUi(1,:) = tempdu*dcos(s%alfau(1,:)) + tempdv*dsin(s%alfau(1,:))
00855 
00856             s%ui(1,:) = s%ui(1,:)*min(par%t/par%taper,1.0d0)
00857             s%zi(1,:) = s%zi(1,:)*min(par%t/par%taper,1.0d0)
00858             s%wi(1,:) = s%wi(1,:)*min(par%t/par%taper,1.0d0)
00859             s%dUi(1,:) = s%dUi(1,:)*min(par%t/par%taper,1.0d0)
00860             ! 3) ts_nonh
00861          elseif (par%wbctype==WBCTYPE_TS_NONH) then
00862             if (xmaster) then
00863                call velocity_Boundary('boun_U.bcf',uig,vig,zig,wig,duig,dvig,sg%ny,&
00864                par%t,isSet_U,isSet_V,isSet_Z,isSet_W,isSet_dU,isSet_dV,isSet_Q)
00865             endif
00866 #ifdef USEMPI
00867             call space_distribute("y",sl,uig,s%ui(1,:))
00868             call space_distribute("y",sl,vig,s%vi(1,:))
00869             call space_distribute("y",sl,zig,s%zi(1,:))
00870             call space_distribute("y",sl,wig,s%wi(1,:))
00871             call space_distribute("y",sl,duig,s%dui(1,:))
00872             call space_distribute("y",sl,dvig,s%dvi(1,:))
00873             call xmpi_bcast(isSet_U)
00874             call xmpi_bcast(isSet_Z)
00875             call xmpi_bcast(isSet_W)
00876             call xmpi_bcast(isSet_dU)
00877             call xmpi_bcast(isSet_dV)
00878 #else
00879             if ( isSet_Q ) then
00880                if (par%nonhq3d == 1 .and. par%nhlay > 0.0d0) then
00881                   ! Calculate the difference velocity from the difference discharges (here both duig and uig are still discharges)
00882                   duig = ( (1.0d0 - 2.0d0*par%nhlay) * uig + duig ) / (  2.0d0 * par%nhlay * s%hu(1,:) *( 1.0d0 - par%nhlay )  )
00883                endif
00884                uig = uig/s%hu(1,:)
00885             endif
00886             s%ui(1,:) = uig
00887             s%vi(1,:) = vig
00888             s%zi(1,:) = zig
00889             s%wi(1,:) = wig
00890             s%dUi(1,:) = duig
00891             s%dVi(1,:) = dvig
00892 #endif
00893             if (.not. isSet_U) s%ui(1,:) = 0.d0
00894             if (.not. isSet_Z) s%zi(1,:) = s%zs(2,:)
00895             if (.not. isSet_W) s%wi(1,:) = s%ws(2,:)
00896             if (.not. isSet_V) then 
00897                s%vi(1,:) = 0.d0
00898                s%isSet_Vbc = 0
00899             else
00900                s%isSet_Vbc = 1
00901             endif
00902             if (par%nonhq3d == 1 .and. par%nhlay > 0.0d0) then
00903                ! Only if the reduced 2-layer model is initiated (P.B. Smit)
00904                if (.not. isSet_dU) s%dUi(1,:) = 0.d0
00905                if (.not. isSet_dV) s%dVi(1,:) = 0.d0
00906             endif
00907          else
00908          endif ! Go over the different wbctypes for nonh
00909       endif ! Go over the different wavemodels
00910       !
00911       ! Finalize: swave and lwave = 0 has influence on boundary
00912       s%ee(1,:,:) = par%swave*s%ee(1,:,:)
00913       if (par%nonhspectrum==0) then
00914          s%ui = par%lwave*(par%order-1.d0)*s%ui
00915       endif
00916    end subroutine wave_bc
00917 
00918    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00919    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00920    !
00921    ! FLOW BOUNDARY CONDITIONS
00922    !
00923    subroutine flow_bc(s,par)
00924       use params,              only: parameters
00925       use spaceparams
00926       use interp,              only: linear_interp
00927       use compute_tide_module, only: tide_boundary_timestep
00928 #ifdef USEMPI
00929       use xmpi_module
00930 #endif
00931       use paramsconst
00932 
00933       implicit none
00934 
00935       type(spacepars), target                     :: s
00936       type(parameters)                            :: par
00937 
00938       integer                                     :: i,j,jj,j1,indt
00939       real*8                                      :: alphanew,vert,windxnow,windynow,factime
00940       real*8                                      :: udnusum,dnusum,vdnvsum,dnvsum
00941       !real*8 , dimension(2)                       :: xzs0,yzs0,szs0
00942       real*8 , dimension(:,:)  ,allocatable,save  :: zs0old,dzs0
00943       real*8 , dimension(:,:)  ,allocatable,save  :: zsmean
00944       real*8 , dimension(:,:)  ,allocatable,save  :: ht,beta,betanp1
00945       real*8 , dimension(:)    ,allocatable,save  :: bn,alpha2,thetai
00946       real*8 , dimension(:,:)  ,allocatable,save  :: dhdx,dhdy,dvdx,dvdy
00947       real*8 , dimension(:,:)  ,allocatable,save  :: dbetadx,dbetady,dvudy
00948       real*8 , dimension(:)    ,allocatable,save  :: inv_ht
00949 
00950 
00951       if (.not. allocated(ht)) then
00952          allocate(ht      (2,s%ny+1))
00953          allocate(dhdx    (2,s%ny+1))
00954          allocate(dhdy    (2,s%ny+1))   ! wwvv not used
00955          allocate(dvdx    (2,s%ny+1))   ! wwvv not used
00956          allocate(dvdy    (2,s%ny+1))
00957          allocate(dvudy   (1,s%ny+1))   ! wwvv not used
00958          allocate(inv_ht  (s%ny+1))
00959          allocate(dbetadx (2,s%ny+1))
00960          allocate(dbetady (2,s%ny+1))
00961          allocate(beta    (2,s%ny+1))
00962          allocate(zsmean  (2,s%ny+1))
00963          allocate(bn      (s%ny+1))
00964          allocate(alpha2  (s%ny+1))
00965          allocate(thetai  (s%ny+1))
00966          allocate(betanp1 (1,s%ny+1))
00967          if (par%tidetype==TIDETYPE_INSTANT) then
00968             allocate(zs0old(s%nx+1,s%ny+1))
00969             allocate(dzs0  (s%nx+1,s%ny+1))
00970             zs0old = s%zs0
00971             dzs0 = 0.d0
00972          endif
00973          ! initialize zsmean
00974          zsmean(1,:) = s%zs(1,:)
00975          zsmean(2,:) = s%zs(s%nx,:)
00976          if (par%hotstart==0) then
00977             ! ToDo: also complete this for zsmean (would need to be added to s% structure)
00978             s%umean = s%uu
00979             s%vmean = s%vv
00980          endif
00981          thetai = 0.d0
00982       endif
00983 
00984       ! Super fast 1D
00985       if (s%ny==0) then
00986          j1 = 1
00987       else
00988          j1 = 2
00989       endif
00990 
00991       ! factime=1.d0/par%cats/par%Trep*par%dt !Jaap: not used anymore
00992       ! jaap: compute epsi based on offshore boundary conditions if epsi = -1
00993       if (par%epsi==-1.d0) then
00994          if (par%swave==1) then
00995             factime = 1.d0/par%cats/par%Trep*par%dt
00996          else
00997             ! need to do something here
00998             factime = 1.d0/60*par%dt
00999          endif
01000       else
01001          factime = par%epsi
01002       endif
01003 
01004       !allocate(szs0(1:2))  ! wwvv changed this, now defined as an automatic array
01005       !allocate(yzs0(1:2))
01006       !
01007       ! Sea boundary at x=0;
01008       !
01009       !
01010       ! UPDATE TIDE AND SURGE
01011       if (par%tidetype==TIDETYPE_INSTANT) then
01012          zs0old = s%zs0  ! store zs0 of old time step
01013          call tide_boundary_timestep(s,par) ! also updates zs0 across domain
01014          where (s%wetz==1)
01015             dzs0 = s%zs0-zs0old
01016             s%zs = s%zs+dzs0
01017          elsewhere
01018             dzs0 = 0.d0
01019          endwhere
01020       else
01021          call tide_boundary_timestep(s,par) ! only updates zs0 on boundaries
01022       endif
01023       !
01024       !Dano: compute umean, vmean only at this location, same for all options; MPI compliant
01025       if (par%tidetype==TIDETYPE_VELOCITY) then
01026          if (xmpi_istop) then
01027             ! make sure we have same umean along whole offshore boundary
01028             udnusum   = sum(s%uu (1,jmin_uu:jmax_uu)*s%dnu(1,jmin_uu:jmax_uu))
01029             dnusum    = sum(s%dnu(1,jmin_uu:jmax_uu))
01030             vdnvsum   = sum(s%vv (1,jmin_vv:jmax_vv)*s%dnv(1,jmin_vv:jmax_vv))
01031             dnvsum    = sum(s%dnv(1,jmin_vv:jmax_vv))
01032          else
01033             udnusum   = 0.d0
01034             dnusum    = 0.d0
01035             vdnvsum   = 0.d0
01036             dnvsum    = 0.d0
01037          endif
01038 #ifdef USEMPI
01039          call xmpi_allreduce(udnusum  ,MPI_SUM)
01040          call xmpi_allreduce(dnusum   ,MPI_SUM)
01041          call xmpi_allreduce(vdnvsum  ,MPI_SUM)
01042          call xmpi_allreduce(dnvsum   ,MPI_SUM)
01043 #endif
01044          s%umean(1,:)=factime*udnusum/dnusum+(1.0d0-factime)*s%umean(1,:)
01045          s%vmean(1,:)=factime*vdnvsum/dnvsum+(1.0d0-factime)*s%vmean(1,:)
01046 
01047       else
01048          s%umean(1,:) = 0.d0
01049          s%vmean(1,:) = 0.d0
01050       endif
01051       !
01052       ! UPDATE (LONG) WAVES
01053       !
01054 #ifdef USEMPI
01055       call xmpi_shift(s%ui,SHIFT_Y_R,1,2)
01056       call xmpi_shift(s%vi,SHIFT_Y_R,1,2)
01057       call xmpi_shift(s%zi,SHIFT_Y_R,1,2)
01058       call xmpi_shift(s%wi,SHIFT_Y_R,1,2)
01059       
01060       call xmpi_shift(s%ui,SHIFT_Y_L,3,4)
01061       call xmpi_shift(s%vi,SHIFT_Y_L,3,4)
01062       call xmpi_shift(s%zi,SHIFT_Y_L,3,4)
01063       call xmpi_shift(s%wi,SHIFT_Y_L,3,4)
01064 #endif      
01065       if (par%wbctype/=WBCTYPE_OFF)then
01066          ! wwvv the following is probably only to do in the top processes, but take care for
01067          ! the mpi_shift calls in horizontal directions
01068          if(xmpi_istop) then
01069             if (par%front==FRONT_ABS_1D) then ! Ad's radiating boundary
01070                !ht(1:2,:)=max(zs0(1:2,:)-zb(1:2,:),par%eps)
01071                !uu(1,:)=2.d0*ui(1,:)-(sqrt(par%g/hh(1,:))*(zs(2,:)-zs0(2,:)))
01072                if (par%freewave==1) then
01073                   s%uu(1,jmin_zs:jmax_zs)=2.0d0*s%ui(1,jmin_zs:jmax_zs)-(sqrt(par%g/s%hh(1,jmin_zs:jmax_zs))*(s%zs(2,jmin_zs:jmax_zs)-s%zs0(2,jmin_zs:jmax_zs))) + s%umean(1,jmin_zs:jmax_zs)
01074                else
01075                   s%uu(1,jmin_zs:jmax_zs)=(1.0d0+sqrt(par%g*s%hh(1,jmin_zs:jmax_zs))/s%cg(1,jmin_zs:jmax_zs))*s%ui(1,jmin_zs:jmax_zs) - &
01076                   (sqrt(par%g/s%hh(1,jmin_zs:jmax_zs))*(s%zs(2,jmin_zs:jmax_zs)-s%zs0(2,jmin_zs:jmax_zs))) + s%umean(1,jmin_zs:jmax_zs)
01077                endif
01078                s%vv(1,jmin_zs:jmax_zs)=s%vv(2,jmin_zs:jmax_zs)
01079                s%zs(1,jmin_zs:jmax_zs)=s%zs(2,jmin_zs:jmax_zs)
01080                if (par%wavemodel==WAVEMODEL_NONH) s%ws(1,jmin_zs:jmax_zs) = s%ws(2,jmin_zs:jmax_zs)
01081             elseif (par%front==FRONT_WAVEFLUME) then ! Ad's radiating boundary
01082                if (par%tidetype==TIDETYPE_VELOCITY) then
01083                   zsmean(1,jmin_zs:jmax_zs) = factime*s%zs(1,jmin_zs:jmax_zs)+(1-factime)*zsmean(1,jmin_zs:jmax_zs)
01084                endif
01085                s%uu(1,jmin_zs:jmax_zs)=(1.0d0+sqrt(par%g*s%hh(1,jmin_zs:jmax_zs))/s%cg(1,jmin_zs:jmax_zs))*s%ui(1,jmin_zs:jmax_zs)-(sqrt(par%g/s%hh(1,jmin_zs:jmax_zs))*(s%zs(2,jmin_zs:jmax_zs)-zsmean(1,jmin_zs:jmax_zs)))
01086                s%vv(1,jmin_zs:jmax_zs)=s%vv(2,jmin_zs:jmax_zs)
01087                s%zs(1,jmin_zs:jmax_zs)=s%zs(2,jmin_zs:jmax_zs)
01088                if (par%wavemodel==WAVEMODEL_NONH) s%ws(1,jmin_zs:jmax_zs) = s%ws(2,jmin_zs:jmax_zs)
01089             elseif (par%front==FRONT_ABS_2D) then ! Van Dongeren (1997), weakly reflective boundary condition
01090                ht(1:2,:)=max(s%zs0(1:2,:)-s%zb(1:2,:),par%eps)
01091                beta=s%uu(1:2,:)-2.*dsqrt(par%g*s%hum(1:2,:))
01092 
01093                !do j=j1,max(s%ny,1)
01094                do j=jmin_zs,jmax_zs
01095                   ! compute gradients in u-points
01096                   dhdx   (1,j) = ( ht  (2,j) - ht  (1,j) ) / s%dsu(1,j)
01097                   dbetadx(1,j) = ( beta(2,j) - beta(1,j) ) / s%dsz(2,j)
01098 
01099                   if (s%ny>0) then
01100                      dvdy   (1,j) = ( s%vu  (1,j+1) - s%vu  (1,j-1) ) / ( s%dnu(1,j)+(s%dnu(1,j-1)+s%dnu(1,j+1))/2 )
01101                      dbetady(1,j) = ( beta(1,j+1) - beta(1,j-1) ) / ( s%dnu(1,j)+(s%dnu(1,j-1)+s%dnu(1,j+1))/2 )
01102                   else
01103                      dvdy   (1,j) = 0.d0
01104                      dbetady(1,j) = 0.d0
01105                   endif
01106 
01107                   inv_ht(j) = 1.d0/s%hum(1,j)
01108 
01109                   bn    (j) = -( s%uu(1,j) - dsqrt(par%g*s%hum(1,j)) ) * dbetadx(1,j) &
01110                   -  s%vu(1,j)                           * dbetady(1,j) &
01111                   +            dsqrt(par%g*s%hum(1,j))   * dvdy   (1,j) &
01112                   +  par%g                             * dhdx   (1,j) &
01113                   +  s%Fx(1,j) * inv_ht(j) / par%rho                    &
01114                   - s%cfu(1,j) * sqrt(s%uu(1,j)**2 + s%vu(1,j)**2) * s%uu(1,j) / s%hum(1,j)
01115                end do
01116 
01117                ! Jaap: Compute angle of incominge wave
01118                thetai = datan(s%vi(1,:)/(s%ui(1,:)+1.d-16))
01119 
01120                !do j=j1,max(s%ny,1)
01121                do j=jmin_zs,jmax_zs
01122 
01123                   betanp1(1,j) = beta(1,j)+ bn(j)*par%dt
01124                   alpha2(j)=-(s%theta0-s%alfaz(1,j)) ! Jaap: this is first estimate
01125                   alphanew = 0.d0
01126 
01127                   do jj=1,50
01128                      !---------- Lower order bound. cond. ---
01129 
01130                      if (par%freewave==1) then ! assuming incoming long wave propagates at sqrt(g*h)
01131                         s%ur(1,j) = dcos(alpha2(j))/(dcos(alpha2(j))+1.d0)&
01132                         *(betanp1(1,j)-s%umean(1,j)+2.d0*DSQRT(par%g*0.5d0*(ht(1,j)+ht(2,j))) &
01133                         -s%ui(1,j)*(dcos(thetai(j))-1.d0)/dcos(thetai(j)))
01134                      else                     ! assuming incoming long wave propagates at s%cg
01135                         s%ur(1,j) = dcos(alpha2(j))/(dcos(alpha2(j))+1.d0)&
01136                         *(betanp1(1,j)-s%umean(1,j)+2.d0*DSQRT(par%g*0.5d0*(ht(1,j)+ht(2,j)))&
01137                         -s%ui(1,j)*(s%cg(1,j)*dcos(thetai(j))- DSQRT(par%g*0.5d0*(ht(1,j)+ht(2,j))) )/&
01138                         (s%cg(1,j)*dcos(thetai(j))))
01139                      endif
01140 
01141                      !vert = velocity of the reflected wave = total-specified
01142                      vert = s%vu(1,j)-s%vmean(1,j)-s%vi(1,j)                    ! Jaap use s%vi instead of s%ui(1,j)*tan(s%theta0)
01143                      alphanew = datan(vert/(s%ur(1,j)+1.d-16))                   ! wwvv can  use atan2 here
01144                      if (alphanew .gt. (par%px*0.5d0)) alphanew=alphanew-par%px
01145                      if (alphanew .le. (-par%px*0.5d0)) alphanew=alphanew+par%px
01146                      if(dabs(alphanew-alpha2(j)).lt.0.001d0) goto 1000    ! wwvv can use exit here
01147                      alpha2(j) = alphanew
01148                   end do
01149 1000              continue
01150                   if (par%ARC==0) then
01151                      s%uu(1,j) = (par%order-1)*s%ui(1,j) + s%umean(1,j)
01152                      s%zs(1,j) = s%zs(2,j)
01153                   else
01154                      !
01155                      s%uu(1,j) = (par%order-1.d0)*s%ui(1,j) + s%ur(1,j) + s%umean(1,j)
01156                      ! zs(1,:) is dummy variable
01157                      ! with a taylor expansion to get to the zs point at index 1 from uu(1) and uu(2)
01158                      s%zs(1,j) = 1.5d0*((betanp1(1,j)-s%uu(1,j))**2/4.d0/par%g+.5d0*(s%zb(1,j)+s%zb(2,j)))- &
01159                      0.5d0*((beta(2,j)   -s%uu(2,j))**2/4.d0/par%g+.5d0*(s%zb(2,j)+s%zb(3,j)))
01160                      ! Ad + Jaap: zs does indeed influence hydrodynamics at boundary --> do higher order taylor expansions to check influence
01161                      ! zs(1,j) = 13.d0/8.d0*((betanp1(1,j)-uu(1,j))**2.d0/4.d0/par%g+.5d0*(zb(1,j)+zb(2,j))) - &
01162                      !           0.75d0*((beta(2,j)-uu(2,j))**2.d0/4.d0/par%g+.5d0*(zb(2,j)+zb(3,j)))        + &
01163                      !           0.125d0*0.5d0*(zs(3,j)+zs(4,j))
01164                   end if
01165                end do
01166 
01167                if (par%wavemodel==WAVEMODEL_NONH.and.xmpi_istop) s%ws(1,jmin_zs:jmax_zs) = s%ws(2,jmin_zs:jmax_zs)
01168                s%vv(1,jmin_zs:jmax_zs)=s%vv(2,jmin_zs:jmax_zs)
01169             else if (par%front==FRONT_WALL) then
01170                !       uu(1,:)=0.d0
01171                !      zs(1,:)=max(zs(2,:),zb(1,:))
01172             else if (par%front==FRONT_NONH_1D) then
01173                !Timeseries Boundary for nonh, only use in combination with instat=8
01174                if (par%ARC==0) then
01175                   s%uu(1,jmin_zs:jmax_zs) = s%ui(1,jmin_zs:jmax_zs)
01176                   s%vv(1,jmin_zs:jmax_zs) = s%vi(1,jmin_zs:jmax_zs)
01177                   s%zs(1,jmin_zs:jmax_zs) = s%zi(1,jmin_zs:jmax_zs)+s%zs0(1,jmin_zs:jmax_zs)
01178                   s%ws(1,jmin_zs:jmax_zs) = s%wi(1,jmin_zs:jmax_zs)
01179                   if (par%nonhq3d == 1 .and. par%nhlay > 0.0d0) then
01180                      ! Only if the reduced 2-layer model is initiated (P.B. Smit)
01181                      s%dU(1,jmin_zs:jmax_zs) = s%dui(1,jmin_zs:jmax_zs)
01182                      !
01183                   endif
01184                   !
01185                else
01186                   !Radiating boundary for short waves:
01187                   s%uu(1,jmin_zs:jmax_zs) = s%ui(1,jmin_zs:jmax_zs)-sqrt(par%g/s%hh(1,jmin_zs:jmax_zs))* & 
01188                                                  (s%zs(2,jmin_zs:jmax_zs)-s%zi(1,jmin_zs:jmax_zs)-s%zs0(2,jmin_zs:jmax_zs)) + & 
01189                                                    s%umean(1,jmin_zs:jmax_zs)
01190                   !
01191                   !                uu(1,:)=  2*ui(1,:)-sqrt(par%g/hh(1,:))*(zs(2,:)        -zs0(2,:))
01192                   if (par%nonhq3d == 1 .and. par%nhlay > 0.0d0) then
01193                      !
01194 
01195                      s%dU(1,jmin_zs:jmax_zs) = s%dui(1,jmin_zs:jmax_zs)
01196                      ! write(*,*) s%dU(1,%)
01197                      !
01198                   endif
01199                   s%vv(1,jmin_zs:jmax_zs) = s%vi(1,jmin_zs:jmax_zs)
01200                   s%zs(1,jmin_zs:jmax_zs) = s%zs(2,jmin_zs:jmax_zs)
01201                   s%ws(1,jmin_zs:jmax_zs) = s%ws(2,jmin_zs:jmax_zs)
01202                endif
01203                if (s%isSet_Vbc == 0) then
01204                   s%vv(1,jmin_zs:jmax_zs)=s%vv(2,jmin_zs:jmax_zs)
01205                endif
01206             endif ! par%front
01207             
01208             if (s%ny>0) then 
01209                if (xmpi_isleft) then
01210                   s%uu(1,1)=s%uu(1,2)
01211                   s%vv(1,1)=s%vv(1,2)
01212                   s%zs(1,1)=max(s%zs(1,2) - s%dzs0dn(1,1)*s%dnv(1,1),s%zb(1,1))
01213                endif
01214                if (xmpi_isright) then
01215                   s%uu(1,s%ny+1)=s%uu(1,s%ny)
01216                   s%vv(1,s%ny+1)=s%vv(1,s%ny)
01217                   s%zs(1,s%ny+1)=max(s%zs(1,s%ny) + s%dzs0dn(1,s%ny+1)*s%dnv(1,s%ny),s%zb(1,s%ny+1))
01218                endif
01219             endif
01220          endif  ! xmpi_istop
01221       endif ! par%wbctype/=WBCTYPE_OFF
01222       !
01223       ! Radiating boundary at x=nx*dx
01224       !
01225       !Dano: compute umean, vmean only at this location, same for all options; MPI compliant
01226       if (par%tidetype==TIDETYPE_VELOCITY) then
01227          ! make sure we have same umean along whole offshore boundary
01228          if (xmpi_isbot) then
01229             udnusum   = sum(s%uu (s%nx,jmin_uu:jmax_uu)*s%dnu(s%nx,jmin_uu:jmax_uu))
01230             dnusum    = sum(s%dnu(s%nx,jmin_uu:jmax_uu))
01231             vdnvsum   = sum(s%vv (s%nx,jmin_vv:jmax_vv)*s%dnv(s%nx,jmin_vv:jmax_vv))
01232             dnvsum    = sum(s%dnv(s%nx,jmin_vv:jmax_vv))
01233          else
01234             udnusum   = 0.d0
01235             dnusum    = 0.d0
01236             vdnvsum   = 0.d0
01237             dnvsum    = 0.d0
01238          endif
01239 #ifdef USEMPI
01240          call xmpi_allreduce(udnusum  ,MPI_SUM)
01241          call xmpi_allreduce(dnusum   ,MPI_SUM)
01242          call xmpi_allreduce(vdnvsum  ,MPI_SUM)
01243          call xmpi_allreduce(dnvsum   ,MPI_SUM)
01244 #endif
01245          s%umean(s%nx,:)=factime*udnusum/dnusum+(1.0d0-factime)*s%umean(s%nx,:)
01246          s%vmean(s%nx,:)=factime*vdnvsum/dnvsum+(1.0d0-factime)*s%vmean(s%nx,:)
01247 
01248       else
01249          s%umean(s%nx,:) = 0.d0
01250          s%vmean(s%nx,:) = 0.d0
01251       endif
01252       if (xmpi_isbot) then
01253          if (par%back==BACK_WALL) then
01254             s%uu(s%nx,jmin_zs:jmax_zs) = 0.d0
01255             s%zs(s%nx+1,jmin_zs:jmax_zs) = s%zs(s%nx,jmin_zs:jmax_zs)
01256             ! zs(nx+1,2:ny) = zs(nx+1,2:ny) + par%dt*hh(nx,2:ny)*uu(nx,2:ny)/(xu(nx+1)-xu(nx)) -par%dt*(hv(nx+1,2:ny+1)*vv(nx+1,2:ny+1)-hv(nx+1,1:ny)*vv(nx+1,1:ny))/(yv(2:ny+1)-yv(1:ny))
01257          elseif (par%back==BACK_ABS_1D) then
01258             s%uu(s%nx,jmin_zs:jmax_zs)=sqrt(par%g/s%hh(s%nx,jmin_zs:jmax_zs))*(s%zs(s%nx,jmin_zs:jmax_zs)-max(s%zb(s%nx,jmin_zs:jmax_zs),s%zs0(s%nx,jmin_zs:jmax_zs)))+s%umean(s%nx,jmin_zs:jmax_zs) ! cjaap: make sure if the last cell is dry no radiating flow is computed...
01259             s%zs(s%nx+1,:)=s%zs(s%nx,:)
01260          elseif (par%back==BACK_ABS_2D) then
01261             ht(1:2,:)=max(s%zs0(s%nx:s%nx+1,:)-s%zb(s%nx:s%nx+1,:),par%eps) !cjaap; make sure ht is always larger than zero
01262 
01263             beta=s%uu(s%nx-1:s%nx,:)+2.*dsqrt(par%g*s%hum(s%nx-1:s%nx,:)) !cjaap : replace s%hh with s%hum
01264 
01265             do j=jmin_zs,jmax_zs
01266                if (s%wetu(s%nx,j)==1) then   ! Robert: dry back boundary points
01267                   ! Compute gradients in u-points....
01268                   dvdy(2,j)=(s%vu(s%nx,j+1)-s%vu(s%nx,j-1))/(2.d0*s%dnu(s%nx,j))
01269                   dhdx(2,j)=(ht(2,j)-ht(1,j))/s%dsu(s%nx,j)
01270                   dbetadx(2,j)=(beta(2,j)-beta(1,j))/s%dsz(s%nx,j)
01271                   dbetady(2,j)=(beta(1,j+1)-beta(1,j-1))/(2.0*s%dnu(s%nx,j))
01272 
01273                   inv_ht(j) = 1.d0/s%hum(s%nx,j)
01274 
01275                   bn(j)=-(s%uu(s%nx,j)+dsqrt(par%g*s%hum(s%nx,j)))*dbetadx(2,j) &
01276                   -s%vu(s%nx,j)*dbetady(2,j)& !Ap s%vu
01277                   -dsqrt(par%g*s%hum(s%nx,j))*dvdy(2,j)&
01278                   +s%Fx(s%nx,j)*inv_ht(j)/par%rho &
01279                   -s%cfu(s%nx,j)*sqrt(s%uu(s%nx,j)**2+s%vu(s%nx,j)**2)*s%uu(s%nx,j)/s%hum(s%nx,j)&
01280                   +par%g*dhdx(2,j)
01281                endif    ! Robert: dry back boundary points
01282             enddo
01283 
01284             do j=jmin_zs,jmax_zs
01285                if (s%wetu(s%nx,j)==1) then                                                     ! Robert: dry back boundary points
01286                   betanp1(1,j) = beta(2,j)+ bn(j)*par%dt                                   !Ap toch?
01287                   alpha2(j)= s%theta0
01288                   alphanew = 0.d0
01289 
01290                   do jj=1,50
01291                      !
01292                      !---------- Lower order bound. cond. ---
01293                      !
01294                      s%ur(s%nx,j) = dcos(alpha2(j))/(dcos(alpha2(j))+1.d0)&
01295                      *((betanp1(1,j)-s%umean(s%nx,j)-2.d0*DSQRT(par%g*0.5*(ht(1,j)+ht(2,j)))))
01296 
01297                      !vert = velocity of the reflected wave = total-specified
01298                      vert = s%vu(s%nx,j)-s%vmean(s%nx,j)                              !Jaap included s%vmean
01299                      alphanew = datan(vert/(s%ur(s%nx,j)+1.d-16))                      ! wwvv maybe better atan2
01300                      if (alphanew .gt. (par%px*0.5d0)) alphanew=alphanew-par%px
01301                      if (alphanew .le. (-par%px*0.5d0)) alphanew=alphanew+par%px
01302                      if(dabs(alphanew-alpha2(j)).lt.0.001) exit    ! wwvv can use exit here
01303                      alpha2(j) = alphanew
01304                   end do
01305 
01306                   s%uu(s%nx,j) = s%ur(s%nx,j) + s%umean(s%nx,j)
01307                   ! Ap replaced zs with extrapolation.
01308                   s%zs(s%nx+1,j) = 1.5*((betanp1(1,j)-s%uu(s%nx,j))**2.d0/4.d0/par%g+.5*(s%zb(s%nx,j)+s%zb(s%nx+1,j)))-&
01309                   0.5*((beta(1,j)-s%uu(s%nx-1,j))**2.d0/4.d0/par%g+.5*(s%zb(s%nx-1,j)+s%zb(s%nx,j)))
01310 
01311                endif   ! Robert: dry back boundary points
01312             enddo
01313          endif  !par%back
01314          s%vv(s%nx+1,jmin_zs:jmax_zs)=s%vv(s%nx,jmin_zs:jmax_zs)
01315          s%uu(s%nx+1,jmin_zs:jmax_zs)=s%uu(s%nx,jmin_zs:jmax_zs)
01316          if (s%ny>0) then
01317             if (xmpi_isleft) then
01318                s%uu(s%nx+1,1)=s%uu(s%nx+1,2)
01319                s%vv(s%nx+1,1)=s%vv(s%nx+1,2)
01320                s%zs(s%nx+1,1)=max(s%zs(s%nx+1,2) - s%dzs0dn(1,1)*s%dnv(1,1),s%zb(1,1))
01321             endif
01322             if (xmpi_isright) then
01323                s%uu(s%nx+1,s%ny+1)=s%uu(s%nx+1,s%ny)
01324                s%vv(s%nx+1,s%ny+1)=s%vv(s%nx+1,s%ny)
01325                s%zs(s%nx+1,s%ny+1)=max(s%zs(s%nx+1,s%ny) + s%dzs0dn(1,s%ny+1)*s%dnv(1,s%ny),s%zb(1,s%ny+1))
01326             endif
01327          endif
01328       endif !xmpi_isbot
01329       !
01330       ! Lateral tide boundary conditions
01331       !
01332       if (s%ny>0) then
01333          do i=imin_zs,imax_zs
01334             if (xmpi_isleft) then
01335                s%zs(i,1)=max(s%zs(i,2) - s%dzs0dn(i,1)*s%dnv(i,1),s%zb(i,1))
01336             endif
01337             if (xmpi_isright) then
01338                s%zs(i,s%ny+1)=max(s%zs(i,s%ny) + s%dzs0dn(i,s%ny+1)*s%dnv(i,s%ny),s%zb(i,s%ny+1))
01339             endif
01340          enddo
01341       endif !s%ny>0
01342 
01343 
01344 
01345       !!! Wind boundary conditions
01346       if (s%windlen>1) then  ! only if non-stationary wind, otherwise waste of computational time
01347          call LINEAR_INTERP(s%windinpt,s%windxts,s%windlen,par%t,windxnow,indt)
01348          call LINEAR_INTERP(s%windinpt,s%windyts,s%windlen,par%t,windynow,indt)
01349          s%windsu = windxnow*dcos(s%alfau) + windynow*dsin(s%alfau)
01350          ! Can we do this more efficiently?
01351          s%windnv = windynow*dcos(s%alfav-0.5d0*par%px) - windxnow*dsin(s%alfav-0.5d0*par%px)
01352       endif
01353    end subroutine flow_bc
01354 
01355    function flow_lat_bc(s,par,bctype,jbc,jn,udvdxb,vdvdyb,viscvb) result(vbc)
01356       use params,         only: parameters
01357       use spaceparams
01358       use paramsconst, only: LR_WALL, LR_NEUMANN_V, LR_NO_ADVEC, LR_NEUMANN, LR_ABS_1D
01359 
01360       type(spacepars),target                  :: s
01361       type(parameters)                        :: par
01362       integer                                 :: bctype
01363       integer                                 :: jbc,jn ! j-index of boundary and j-index of neighbouring cell
01364       ! varies for xmpi_isleft and xmpi_isright
01365       real*8,dimension(s%nx+1)                :: udvdxb,vdvdyb,viscvb   ! advection terms from flow timestep
01366       real*8,dimension(s%nx+1)                :: vbc    ! result vector for boundary flow
01367       integer                                 :: i      ! internal variables
01368       real*8                                  :: advterm
01369       real*8,save                             :: fc
01370 
01371 
01372       if (par%t<=par%dt) fc =2.d0*par%wearth*sin(par%lat)
01373 
01374       if (s%ny==0) then      ! 1D models have special case
01375          if (bctype==LR_WALL) then
01376             vbc(:) = 0.d0 ! Only this bc scheme can be applied to s%ny==0 models
01377          else
01378             vbc(:) = s%vv(:,jbc)  ! return whatever was already calculated in the flow routine for the cross shore row
01379          endif
01380       else
01381          select case (bctype)
01382           case (LR_WALL)
01383             ! No flow at boundary
01384             vbc(:) = 0.d0
01385           case (LR_NEUMANN_V)
01386             ! Calculate vv at boundary using identical forcing as (:,2), but with dzsdy determined from (:,1), which includes
01387             ! the tide-driven water level gradient as zs(:,1) = zs(:,2) + dzsdytide
01388             !
01389             ! in flow timestep we calculate:
01390             ! vv(jn) = vvold(jn)-dt(gDZS(jn) + R(jn))
01391             !   -> vvold(jn) = vv(jn) + dt(gDZS(jn) + R(jn))
01392             !
01393             ! we state in bc that:
01394             ! vv(jbc) = vvold(jn)-dt(gDZS(jbc) + R(jn))
01395             !   -> vv(jbc) = ( vv(jn) + dt(gDZS(jn) + R(jn)) )-dt(gDZS(jbc) + R(jn))
01396             !   -> vv(jbc) = vv(jn) + dt(gDZS(jn)) - dt(gDZS(jbc)) + dt(R(jn)) - dt(R(jn))
01397             !   -> vv(jbc) = vv(jn) + dt(gDZS(jn)-gDZS(jbc))
01398             !   -> vv(jbc) = vv(jn) + dtg(DZS(jn)-DZS(jbc))
01399             !                  vbc(:) = (vv(:,jn)+par%dt*par%g*(dzsdy(i,jn)-dzsdy(i,jbc))) * wetv(:,jbc)
01400             ! AANPASSING: Neumann zonder getij
01401             ! Dano/Jaap: Je kunt niet druk gradient a.g.v getij meenemen zonder ook andere forcerings termen (bijv bodem wrijving)
01402             ! uit te rekenen. In geval van getij gradient heb je een meer complexe neumann rvw die jij "free" noemt
01403             vbc(:) = s%vv(:,jn)
01404           case (LR_NO_ADVEC)
01405             ! We allow vv at the boundary to be calulated from NLSWE, but only include the advective terms if
01406             ! they decrease the flow velocity
01407             do i=2,s%nx
01408                if (s%wetv(i,jbc)==1) then
01409                   advterm = udvdxb(i)+vdvdyb(i)-viscvb(i)+ fc*s%uv(i,jbc)
01410                   if (s%vv(i,jbc)>0.d0) then
01411                      advterm = max(advterm,0.d0)
01412                   elseif (s%vv(i,jbc)<0.d0) then
01413                      advterm = min(advterm,0.d0)
01414                   else
01415                      advterm = 0.d0
01416                   endif
01417                   vbc(i) = s%vv(i,jbc)- par%dt*(advterm &
01418                   + par%g*s%dzsdy(i,jbc)&
01419                   + s%tauby(i,jbc)/(par%rho*s%hvm(i,jbc)) &
01420                   - par%lwave*s%Fy(i,jbc)/(par%rho*s%hvm(i,jbc)) &
01421                   - par%rhoa*par%Cd*s%windnv(i,jbc)*sqrt(s%windsu(i,jbc)**2+s%windnv(i,jbc)**2)/(par%rho*s%hvm(i,jbc)))  ! Kees: wind correction
01422                   ! Robert: no Coriolis because dependecy u in this combination of wall / Neumann
01423                else
01424                   vbc(i) = 0.d0
01425                endif
01426             enddo
01427             ! now fill i=1 and i=nx+1
01428             vbc(1) = vbc(2) * s%wetv(1,jbc)
01429             vbc(s%nx+1) = vbc(s%nx) * s%wetv(s%nx+1,jbc)
01430           case (LR_NEUMANN)
01431             ! Dano/Jaap: En dit is dan dus complexe vorm van Neumann (zoals in Delft3D) met getij
01432             ! We allow vv at the boundary to be calulated from NLSWE without any limitations
01433             do i=2,s%nx
01434                if (s%wetv(i,jbc)==1) then
01435                   vbc(i) = s%vv(i,jbc)- par%dt*(udvdxb(i)+vdvdyb(i)-viscvb(i)&
01436                   + par%g*s%dzsdy(i,jbc)&
01437                   + s%tauby(i,jbc)/(par%rho*s%hvm(i,jbc)) &
01438                   - par%lwave*s%Fy(i,jbc)/(par%rho*s%hvm(i,jbc)) &
01439                   + fc*s%uv(i,jbc) &
01440                   - par%rhoa*par%Cd*s%windnv(i,jbc)*sqrt(s%windsu(i,jbc)**2+s%windnv(i,jbc)**2)/(par%rho*s%hvm(i,jbc)))  ! Kees: wind correction
01441                else
01442                   vbc(i) = 0.d0
01443                endif
01444             enddo
01445             ! now fill i=1 and i=nx+1
01446             vbc(1) = vbc(2) * s%wetv(1,jbc)
01447             vbc(s%nx+1) = vbc(s%nx) * s%wetv(s%nx+1,jbc)
01448           case (LR_ABS_1D)
01449             ! Dano: weakly reflective boundary
01450             do i=2,s%nx
01451                if (s%wetv(i,jbc)==1) then
01452                   vbc(i) = sqrt(par%g/s%hh(i,jn))*(s%zs(i,jn)-max(s%zb(i,jn),s%zs0(i,jn)))*(jbc-jn)
01453                   s%zs(i,jbc)=s%zs(i,jn)
01454                else
01455                   vbc(i) = 0.d0
01456                endif
01457             enddo
01458             ! now fill i=1 and i=nx+1
01459             vbc(1) = vbc(2) * s%wetv(1,jbc)
01460             vbc(s%nx+1) = vbc(s%nx) * s%wetv(s%nx+1,jbc)
01461          end select
01462       endif
01463    end function flow_lat_bc
01464 
01465 
01466    subroutine discharge_boundary_h(s,par)
01467       use params,         only: parameters
01468       use spaceparamsdef
01469       use xmpi_module
01470       use interp,         only: linear_interp
01471 
01472 
01473       implicit none
01474 
01475       type(spacepars),target                  :: s
01476       type(parameters)                        :: par
01477 
01478       integer                                 :: i,indx
01479       integer                                 :: m1,m2,n1,n2
01480       integer                                 :: m1l,m2l,n1l,n2l
01481       real*8                                  :: qnow,A,CONST
01482       logical                                 :: indomain,isborder
01483       integer                                 :: ishift,jshift
01484       integer                                 :: iminl,imaxl,jminl,jmaxl
01485 
01486 #ifdef USEMPI
01487       ishift  = s%is(xmpi_rank+1)-1
01488       jshift  = s%js(xmpi_rank+1)-1
01489 #else
01490       ishift  = 0
01491       jshift  = 0
01492 #endif
01493       iminl = imin_zs
01494       imaxl = imax_zs
01495       jminl = jmin_zs
01496       jmaxl = jmax_zs
01497       if (xmpi_istop) then
01498          iminl = imin_zs-1
01499       endif
01500       if (xmpi_isbot) then
01501          imaxl = imax_zs+1
01502       endif
01503       if (xmpi_isleft) then
01504          jminl = jmin_zs-1
01505       endif
01506       if (xmpi_isright) then
01507          jmaxl = jmax_zs+1
01508       endif
01509 
01510       ! loop through discharge location
01511       do i = 1,par%ndischarge
01512          if (s%pntdisch(i).eq.0) then
01513 
01514             ! interpolate discharge timeseries to current time
01515             call linear_interp(s%tdisch,s%qdisch(:,i),par%ntdischarge,par%t,qnow,indx)
01516 
01517             m1 = s%pdisch(i,1)
01518             n1 = s%pdisch(i,2)
01519             m2 = s%pdisch(i,3)
01520             n2 = s%pdisch(i,4)
01521 
01522             ! convert to local coordinates
01523             m1l = m1-ishift
01524             m2l = m2-ishift
01525             n1l = n1-jshift
01526             n2l = n2-jshift
01527 
01528             indomain =  (   m1l >= iminl .and. m1l <= imaxl .and.         &
01529             n1l >=jminl .and. n1l <= jmaxl       ) .or.  &
01530             (   m2l >=iminl .and. m2l <= imaxl .and.         &
01531             n2l >=jminl  .and. n2l <= jmaxl       )
01532 
01533             m1l = min(max(m1l,1),s%nx)
01534             m2l = min(max(m2l,1),s%nx)
01535             n1l = min(max(n1l,1),s%ny)
01536             n2l = min(max(n2l,1),s%ny)
01537 
01538             A = 0.d0
01539 
01540             ! add momentum in either u- or v-direction
01541             if (n1.eq.n2) then
01542 
01543                if (indomain) then
01544                   isborder = (n1l.eq.1 .and. xmpi_isleft) .or. (n1l.eq.s%ny .and. xmpi_isright)
01545                   m1l=max(m1l,iminl)
01546                   m2l=min(m2l,imaxl)
01547 
01548                   ! make sure discharge is an inflow at border and water levels are defined
01549                   if (isborder) then
01550                      if (n1l.gt.1) then
01551                         qnow = -1*qnow
01552                         s%hv(m1l:m2l,n1l) = s%hh(m1l:m2l,n1l)
01553                      elseif (n1l.lt.s%ny) then
01554                         s%hv(m1l:m2l,n1l) = s%hh(m1l:m2l,n1l+1)
01555                      endif
01556                   endif
01557 
01558                   A = sum(s%hv(m1l:m2l,n1l)**1.5*s%dsv(m1l:m2l,n1l))
01559                endif
01560 
01561 #ifdef USEMPI
01562                call xmpi_allreduce(A,MPI_SUM)
01563 #endif
01564 
01565                ! compute distribution of discharge over discharge cells according to:
01566                !     vv = CONST * hv^0.5
01567                !     qy = CONST * hv^1.5
01568                !     Q  = CONST * hv^1.5 * dsv
01569 
01570                if (indomain) then
01571                   CONST = qnow/max(A,par%eps)
01572                   s%vv(m1l:m2l,n1l) = CONST*sqrt(s%hv(m1l:m2l,n1l))
01573                   s%qy(m1l:m2l,n1l) = CONST*sqrt(s%hv(m1l:m2l,n1l))*s%hv(m1l:m2l,n1l)
01574                endif
01575 
01576             elseif (m1.eq.m2) then
01577 
01578                if (indomain) then
01579                   isborder = (m1l.eq.1 .and. xmpi_istop) .or. (m1l.eq.s%nx .and. xmpi_isbot)
01580                   n1l=max(n1l,jminl)
01581                   n2l=min(n2l,jmaxl)
01582 
01583                   ! make sure discharge is an inflow at border and water levels are defined
01584                   if (isborder) then
01585                      if (m1l.gt.1) then
01586                         qnow = -1*qnow
01587                         s%hu(m1l,n1l:n2l) = s%hh(m1l,n1l:n2l)
01588                      elseif (m1l.lt.s%nx) then
01589                         s%hu(m1l,n1l:n2l) = s%hh(m1l+1,n1l:n2l)
01590                      endif
01591                   endif
01592 
01593                   A = sum(s%hu(m1l,n1l:n2l)**1.5*s%dnu(m1l,n1l:n2l))
01594                endif
01595 
01596 #ifdef USEMPI
01597                call xmpi_allreduce(A,MPI_SUM)
01598 #endif
01599 
01600                ! compute distribution of discharge over discharge cells according to:
01601                !     uu = CONST * hu^0.5
01602                !     qx = CONST * hu^1.5
01603                !     Q  = CONST * hu^1.5 * dnu
01604 
01605                if (indomain) then
01606                   CONST = qnow/max(A,par%eps)
01607                   s%uu(m1l,n1l:n2l) = CONST*sqrt(s%hu(m1l,n1l:n2l))
01608                   s%qx(m1l,n1l:n2l) = CONST*sqrt(s%hu(m1l,n1l:n2l))*s%hu(m1l,n1l:n2l)
01609                endif
01610             endif
01611          endif
01612       enddo
01613    end subroutine discharge_boundary_h
01614 
01615    subroutine discharge_boundary_v(s,par)
01616       use params,         only: parameters
01617       use spaceparamsdef
01618       use interp,         only: linear_interp
01619 #ifdef USEMPI
01620       use xmpi_module
01621 #endif
01622 
01623       implicit none
01624 
01625       type(spacepars),target                  :: s
01626       type(parameters)                        :: par
01627 
01628       integer                                 :: i,indx
01629       integer                                 :: m1,n1
01630       integer                                 :: m1l,n1l
01631       real*8                                  :: qnow
01632       integer                                 :: ishift,jshift
01633 
01634 
01635 #ifdef USEMPI
01636       ishift  = s%is(xmpi_rank+1)-1
01637       jshift  = s%js(xmpi_rank+1)-1
01638 #else
01639       ishift  = 0
01640       jshift  = 0
01641 #endif
01642 
01643       do i = 1,par%ndischarge
01644          if (s%pntdisch(i).eq.1) then
01645             call linear_interp(s%tdisch,s%qdisch(:,i),par%ntdischarge,par%t,qnow,indx)
01646 
01647             m1 = s%pdisch(i,1)
01648             n1 = s%pdisch(i,2)
01649 
01650             ! convert to local coordinates
01651             m1l = min(max(m1-ishift,1),s%nx)
01652             n1l = min(max(n1-jshift,1),s%ny)
01653 
01654             ! add mass
01655             s%zs(m1l,n1l) = s%zs(m1l,n1l)+qnow*par%dt*s%dsdnzi(m1l,n1l)
01656          endif
01657       enddo
01658    end subroutine discharge_boundary_v
01659 
01660    !
01661    !==============================================================================
01662    subroutine velocity_Boundary(bcfile,ug,vg,zg,wg,dug,dvg,nyg,t,isSet_U,isSet_V,isSet_Z,isSet_W,isSet_dU, &
01663    isSet_dV,isSet_Q,force_init,bcst)
01664       !==============================================================================
01665       !
01666 
01667       !-------------------------------------------------------------------------------
01668       !                             DECLARATIONS
01669       !-------------------------------------------------------------------------------
01670 
01671       !
01672       !--------------------------        PURPOSE         ----------------------------
01673       !
01674       !   Reads boundary values for the velocity from a file. Used as forcing in the
01675       !   nonh module
01676 
01677       !--------------------------        METHOD         ----------------------------
01678 
01679 
01680       !--------------------------     DEPENDENCIES       ----------------------------
01681 
01682       use params
01683       use xmpi_module,    only: Halt_Program, xmaster
01684       use spaceparamsdef, only: spacepars
01685       use logging_module, only: writelog, report_file_read_error
01686       use readkey_module, only: lowercase
01687       use mnemmodule,     only: maxnamelen
01688 
01689       implicit none
01690 
01691       include 'nh_pars.inc'               !Default precision etc.
01692 
01693       !--------------------------     ARGUMENTS          ----------------------------
01694       !
01695       character(len=*)              ,intent(in)    :: bcfile
01696       integer(kind=iKind)           ,intent(in)    :: nyg
01697       real(kind=rKind),dimension(nyg+1)            :: ug,vg,zg,wg,dug,dvg
01698       real(kind=rKind)                ,intent(in)  :: t
01699       logical,intent(out)                          :: isSet_U,isSet_V,isSet_Z,isSet_W,isSet_dU,isSet_dV,isSet_Q
01700       logical,intent(in),optional                  :: force_init
01701       real(kind=rKind),intent(in),optional         :: bcst
01702       !
01703 
01704       !--------------------------     LOCAL VARIABLES    ----------------------------
01705       character(len=iFileNameLen),save          :: filename_U = ''
01706       integer                    ,save          :: unit_U = iUnit_U
01707 
01708       logical,save                              :: lVarU = .false.
01709       logical,save                              :: lIsEof = .false.
01710       logical,save                              :: lNH_boun_U  = .false.
01711       logical,save                              :: initialize  = .true.
01712       logical                                   :: lExists,lOpened
01713       character(slen)                          :: string
01714       character(len=2),allocatable,dimension(:),save :: header
01715       integer(kind=ikind)                       :: iAllocErr,ier
01716       integer(kind=ikind),save                  :: nvar
01717 
01718       integer(kind=ikind),save                  :: iZ = 0
01719       integer(kind=ikind),save                  :: iU = 0
01720       integer(kind=ikind),save                  :: iV = 0
01721       integer(kind=ikind),save                  :: idU = 0
01722       integer(kind=ikind),save                  :: idV = 0
01723       integer(kind=ikind),save                  :: iQ  = 0
01724       integer(kind=ikind),save                  :: idQ = 0
01725       integer(kind=ikind),save                  :: iW = 0
01726       integer(kind=ikind),save                  :: iT = 0
01727       integer(kind=ikind)                       :: i
01728 
01729       logical                                   :: fi_local
01730       real(kind=rKind)                          :: bcstarttime
01731 
01732 
01733       real(kind=rKind),allocatable,dimension(:,:)    :: tmp
01734 
01735       real(kind=rKind),allocatable,dimension(:),save :: u0 !
01736       real(kind=rKind),allocatable,dimension(:),save :: u1 !
01737 
01738       real(kind=rKind),allocatable,dimension(:),save :: v0 !
01739       real(kind=rKind),allocatable,dimension(:),save :: v1 !
01740 
01741       real(kind=rKind),allocatable,dimension(:),save :: z0 !
01742       real(kind=rKind),allocatable,dimension(:),save :: z1 !
01743 
01744       real(kind=rKind),allocatable,dimension(:),save :: w0 !
01745       real(kind=rKind),allocatable,dimension(:),save :: w1 !
01746 
01747       real(kind=rKind),allocatable,dimension(:),save :: du0 !
01748       real(kind=rKind),allocatable,dimension(:),save :: du1 !
01749 
01750       real(kind=rKind),allocatable,dimension(:),save :: dv0 !
01751       real(kind=rKind),allocatable,dimension(:),save :: dv1 !
01752 
01753       real(kind=rKind),save                          :: t0 = 0.
01754       real(kind=rKind),save                          :: t1 = 0.
01755 
01756       !-------------------------------------------------------------------------------
01757       !                             IMPLEMENTATION
01758       !-------------------------------------------------------------------------------
01759 
01760       if (xmaster) then
01761          if (present(bcst)) then
01762             bcstarttime = bcst
01763          else
01764             bcstarttime = 0.d0
01765          endif
01766 
01767          if (present(force_init)) then
01768             fi_local = force_init
01769          else
01770             fi_local = .false.
01771          endif
01772 
01773          if (bcfile/=filename_U .or. fi_local) then
01774             filename_U=trim(bcfile)
01775             initialize = .true.
01776          endif
01777          !
01778          ! INITIALIZE NEW FILE
01779          !
01780          if (initialize) then
01781             initialize = .false.
01782 
01783             !Does the file exist and is it already opened (reuse files?)
01784             inquire(file=trim(filename_U),EXIST=lExists,OPENED=lOpened)
01785 
01786             ! Close previous file if needed
01787             if(lOpened) then
01788                close(unit_U)
01789             endif
01790 
01791             ! Deallocate previous arrays if needed
01792             if (allocated(header)) deallocate(header)
01793             if (allocated(tmp)) deallocate(tmp)
01794             if (allocated(u0)) deallocate(u0)
01795             if (allocated(u1)) deallocate(u1)
01796             if (allocated(v0)) deallocate(v0)
01797             if (allocated(v1)) deallocate(v1)
01798             if (allocated(z0)) deallocate(z0)
01799             if (allocated(z1)) deallocate(z1)
01800             if (allocated(w0)) deallocate(w0)
01801             if (allocated(w1)) deallocate(w1)
01802             if (allocated(du0)) deallocate(du0)
01803             if (allocated(dv0)) deallocate(dv0)
01804             if (allocated(du1)) deallocate(du1)
01805             if (allocated(dv1)) deallocate(dv1)
01806 
01807             if (lExists) then
01808                !If exists, open
01809                open(unit_U,file=filename_U,access='SEQUENTIAL',action='READ',form='FORMATTED')
01810                lNH_boun_U = .true.
01811             else
01812                lNH_boun_U = .false.
01813                call writelog('lswe','','Error bc file does not exist: ',trim(filename_U))
01814                call halt_program
01815                return
01816             endif
01817 
01818 
01819             !SCALAR OR VECTOR INPUT?
01820             read(unit_U,fmt=*,iostat=ier) string
01821             if (ier .ne. 0) then
01822                call report_file_read_error(filename_U)
01823             endif
01824             string = lowercase(string)
01825             if   (string == 'scalar') then
01826                lVaru = .false.
01827             elseif (string == 'vector') then
01828                lVaru = .true.
01829             else
01830 
01831             endif
01832 
01833             !READ NUMBER OF VARIABLES
01834             read(unit_U,fmt=*,iostat=ier) nvar
01835             if (ier .ne. 0) then
01836                call report_file_read_error(filename_U)
01837             endif
01838 
01839             !READ HEADER LINES
01840             allocate(header(nvar))
01841             read(unit_U,fmt=*,iostat=ier) header
01842             if (ier .ne. 0) then
01843                call report_file_read_error(filename_U)
01844             endif
01845 
01846             do i=1,nvar
01847                if (header(i) == 'z' .or. header(i) == 'Z' .or. &
01848                header(i) == 'zs' .or. header(i) == 'ZS' .or. &
01849                header(i) == 'Zs') then
01850                   iZ = i;
01851                elseif (header(i) == 't' .or. header(i) == 'T') then
01852                   iT = i;
01853                elseif (header(i) == 'u' .or. header(i) == 'U') then
01854                   iU = i;
01855                elseif (header(i) == 'v' .or. header(i) == 'V') then
01856                   iV = i;
01857                elseif (header(i) == 'w' .or. header(i) == 'W') then
01858                   iW = i;
01859                elseif (header(i) == 'dU' .or. header(i) == 'DU') then
01860                   idU = i;
01861                elseif (header(i) == 'dV' .or. header(i) == 'DV') then
01862                   idV = i;
01863                elseif (header(i) == 'q' .or. header(i) == 'Q') then
01864                   iQ = i;
01865                   iU = i;
01866                elseif (header(i) == 'dq' .or. header(i) == 'dQ') then
01867                   idQ = i;
01868                   idU = i
01869                endif
01870             enddo
01871 
01872             !Allocate arrays at old and new timelevel
01873             if (iU > 0) then
01874                allocate(u0(nyg+1),stat=iAllocErr); if (iAllocErr /= 0) call Halt_program
01875                allocate(u1(nyg+1),stat=iAllocErr); if (iAllocErr /= 0) call Halt_program
01876                u0 = 0.0d0
01877                u1 = 0.0d0
01878             endif
01879 
01880             if (iV > 0) then
01881                allocate(v0(nyg+1),stat=iAllocErr); if (iAllocErr /= 0) call Halt_program
01882                allocate(v1(nyg+1),stat=iAllocErr); if (iAllocErr /= 0) call Halt_program
01883                v0 = 0.0d0
01884                v1 = 0.0d0
01885             endif
01886 
01887             if (iZ > 0) then
01888                allocate(z0(nyg+1),stat=iAllocErr); if (iAllocErr /= 0) call Halt_program
01889                allocate(z1(nyg+1),stat=iAllocErr); if (iAllocErr /= 0) call Halt_program
01890                z0 = 0.0d0
01891                z1 = 0.0d0
01892             endif
01893 
01894             if (iW > 0) then
01895                allocate(w0(nyg+1),stat=iAllocErr); if (iAllocErr /= 0) call Halt_program
01896                allocate(w1(nyg+1),stat=iAllocErr); if (iAllocErr /= 0) call Halt_program
01897                w0 = 0.0d0
01898                w1 = 0.0d0
01899             endif
01900 
01901             if (idU > 0) then
01902                allocate(du0(nyg+1),stat=iAllocErr); if (iAllocErr /= 0) call Halt_program
01903                allocate(du1(nyg+1),stat=iAllocErr); if (iAllocErr /= 0) call Halt_program
01904                du0 = 0.0d0
01905                du1 = 0.0d0
01906             endif
01907             if (idV > 0) then
01908                allocate(dv0(nyg+1),stat=iAllocErr); if (iAllocErr /= 0) call Halt_program
01909                allocate(dv1(nyg+1),stat=iAllocErr); if (iAllocErr /= 0) call Halt_program
01910                dv0 = 0.0d0
01911                dv1 = 0.0d0
01912             endif
01913 
01914             allocate(tmp(nyg+1,nvar-1))
01915             !Read two first timelevels
01916             call velocity_Boundary_read(t0,tmp,Unit_U,lVaru,lIsEof,nvar)
01917             t0 = t0+bcstarttime
01918             if (iU >0) u0 = tmp(:,iU-1)
01919             if (iV >0) v0 = tmp(:,iV-1)
01920             if (iZ >0) z0 = tmp(:,iZ-1)
01921             if (iW >0) w0 = tmp(:,iW-1)
01922             if (idU >0) dU0 = tmp(:,idU-1)
01923             if (idV >0) dV0 = tmp(:,idV-1)
01924             !
01925             if (lIsEof) then
01926                t1=t0
01927                if (iU >0) u1=u0
01928                if (iV >0) v1=v0
01929                if (iZ >0) z1=z0
01930                if (iW >0) w1=w0
01931                if (idU >0) du1=du0
01932                if (idV >0) dv1=dv0
01933             else
01934                call velocity_Boundary_read(t1,tmp,Unit_U,lVaru,lIsEof,nvar)
01935                t1 = t1+bcstarttime
01936                if (iU >0) u1 = tmp(:,iU-1)
01937                if (iV >0) v1 = tmp(:,iV-1)
01938                if (iZ >0) z1 = tmp(:,iZ-1)
01939                if (iW >0) w1 = tmp(:,iW-1)
01940                if (idu >0) du1 = tmp(:,idU-1)
01941                if (idv >0) dv1 = tmp(:,idV-1)
01942             endif
01943             deallocate(tmp)
01944             if (iU > 0) then
01945                ug  = u0 + (u1-u0)*(t-t0)/(t1-t0)
01946                isSet_U = .true.
01947             else
01948                ug = 0
01949                isSet_U = .false.
01950             endif
01951 
01952             if (iV > 0) then
01953                vg  = v0 + (v1-v0)*(t-t0)/(t1-t0)
01954                isSet_V = .true.
01955             else
01956                vg = 0
01957                isSet_V = .false.
01958             endif
01959 
01960             if (iZ > 0) then
01961                zg = z0 + (z1-z0)*(t-t0)/(t1-t0)
01962                isSet_Z = .true.
01963             else
01964                zg = 0
01965                isSet_Z = .false.
01966             endif
01967             if (iW > 0) then
01968                wg = w0 + (w1-w0)*(t-t0)/(t1-t0)
01969                isSet_W = .true.
01970             else
01971                wg = 0
01972                isSet_W = .false.
01973             endif
01974 
01975             if (idu > 0) then
01976                dug = dU0 + (dU1-dU0)*(t-t0)/(t1-t0)
01977                isSet_dU = .true.
01978             else
01979                dug = 0
01980                isSet_dU = .false.
01981             endif
01982 
01983             if (idv > 0) then
01984                dvg = dV0 + (dV1-dV0)*(t-t0)/(t1-t0)
01985                isSet_dV = .true.
01986             else
01987                dvg = 0
01988                isSet_dV = .false.
01989             endif
01990 
01991             if (iQ > 0) then
01992                !
01993                isSet_Q = .true.
01994             else
01995                isSet_Q = .false.
01996                !
01997             endif
01998 
01999 
02000             return
02001          endif   ! initialize
02002          !
02003          ! REGULAR TIMESTEP READ BOUNDARY CONDITIONS
02004          !
02005          if (lNH_boun_U) then
02006             if (.not. lIsEof) then
02007                allocate(tmp(nyg+1,nvar-1))
02008                !If current time not located within interval read next line
02009                do while (.not. (t>=t0 .and. t<t1))
02010                   t0 = t1
02011                   if (iU >0) u0 = u1
02012                   if (iV >0) v0 = v1
02013                   if (iZ >0) z0 = z1
02014                   if (iW >0) w0 = w1
02015                   if (idu >0) du0 = du1
02016                   if (idv >0) dv0 = dv1
02017                   call velocity_Boundary_read(t1,tmp,Unit_U,lVaru,lIsEof,nvar)
02018                   t1 = t1+bcstarttime
02019                   if (iU >0) u1 = tmp(:,iU-1)
02020                   if (iV >0) v1 = tmp(:,iV-1)
02021                   if (iZ >0) z1 = tmp(:,iZ-1)
02022                   if (iW >0) w1 = tmp(:,iW-1)
02023                   if (idu >0) du1 = tmp(:,idu-1)
02024                   if (idv >0) dv1 = tmp(:,idv-1)
02025                   if (lIsEof) exit !Exit on end of file condition
02026                end do
02027                deallocate(tmp)
02028 
02029                if(lIsEof) then
02030                   if (iU >0) ug = u1
02031                   if (iV >0) vg = v1
02032                   if (iZ >0) zg = z1
02033                   if (iW >0) wg = w1
02034                   if (idu >0) dug = du1
02035                   if (idv >0) dvg = dv1
02036                   if (iQ > 0) then
02037                      isSet_Q = .true.
02038                   else
02039                      isSet_Q = .false.
02040                   endif
02041                   return
02042                else
02043                   !Linear interpolation of u in time
02044                   if (iU > 0) then
02045                      ug  = u0 + (u1-u0)*(t-t0)/(t1-t0)
02046                      isSet_U = .true.
02047                   else
02048                      ug = 0
02049                      isSet_U = .false.
02050                   endif
02051 
02052                   if (iV > 0) then
02053                      vg  = v0 + (v1-v0)*(t-t0)/(t1-t0)
02054                      isSet_V = .true.
02055                   else
02056                      vg = 0
02057                      isSet_V = .false.
02058                   endif
02059 
02060                   if (iZ > 0) then
02061                      zg = z0 + (z1-z0)*(t-t0)/(t1-t0)
02062                      isSet_Z = .true.
02063                   else
02064                      zg = 0
02065                      isSet_Z = .false.
02066                   endif
02067                   if (iW > 0) then
02068                      wg = w0 + (w1-w0)*(t-t0)/(t1-t0)
02069                      isSet_W = .true.
02070                   else
02071                      wg = 0
02072                      isSet_W = .false.
02073                   endif
02074                   if (idu > 0) then
02075                      dug = dU0 + (dU1-dU0)*(t-t0)/(t1-t0)
02076                      isSet_dU = .true.
02077                   else
02078                      dug = 0
02079                      isSet_dU = .false.
02080                   endif
02081                   if (idv > 0) then
02082                      dvg = dV0 + (dV1-dV0)*(t-t0)/(t1-t0)
02083                      isSet_dV = .true.
02084                   else
02085                      dvg = 0
02086                      isSet_dV = .false.
02087                   endif
02088                   !
02089                   if (iQ > 0) then
02090                      !
02091                      isSet_Q = .true.
02092                      !
02093                   else
02094                      isSet_Q = .false.
02095                   endif
02096                   !
02097                endif
02098             else
02099                !If end of file the last value which was available is used until the end of the computation
02100                if (iU > 0) ug = u1
02101                if (iV > 0) vg = v1
02102                if (iZ > 0) zg = z1
02103                if (idu > 0) dug = dU1
02104                if (idv > 0) dvg = dV1
02105                if (iW > 0) wg = w1
02106                if (iQ > 0) then
02107                   isSet_Q = .true.
02108                else
02109                   isSet_Q = .false.
02110                endif
02111             endif ! .not. lIsEof
02112          endif ! lNH_boun_U
02113       endif ! xmaster
02114    end subroutine velocity_Boundary
02115 
02116    !==============================================================================
02117    subroutine velocity_Boundary_read(t,vector,iUnit,isvec,iseof,nvar)
02118       !==============================================================================
02119 
02120       !--------------------------        PURPOSE         ----------------------------
02121 
02122       ! Reads scalar/vector for timeseries
02123 
02124       !-------------------------------------------------------------------------------
02125       !                             DECLARATIONS
02126       !-------------------------------------------------------------------------------
02127 
02128 
02129 
02130       !                                - NONE -
02131 
02132       !--------------------------     DEPENDENCIES       ----------------------------
02133 
02134       use xmpi_module, only: Halt_Program
02135       use logging_module, only: report_file_read_error
02136 
02137       implicit none
02138 
02139       include 'nh_pars.inc'               !Default precision etc.
02140       !--------------------------     ARGUMENTS          ----------------------------
02141 
02142       real(kind=rKind),intent(inout)                   :: t
02143       real(kind=rKind),intent(inout),dimension(:,:)    :: vector
02144       integer(kind=iKind),intent(in)                   :: iUnit
02145       integer(kind=iKind),intent(in)                   :: nvar
02146       logical            ,intent(in)                   :: isvec
02147       logical            ,intent(out)                  :: iseof
02148 
02149       !--------------------------     LOCAL VARIABLES    ----------------------------
02150 
02151       real(kind=rKind)                            :: scalar(nvar-1)
02152       integer(kind=iKind)                         :: i
02153       integer(kind=iKind)                         :: ioStat
02154       character(len=slen)                         :: ername
02155 
02156       !-------------------------------------------------------------------------------
02157       !                             IMPLEMENTATION
02158       !-------------------------------------------------------------------------------
02159 
02160 
02161       iseof = .false.
02162 
02163       if (isvec) then
02164          read(iUnit,ioStat=ioStat,fmt=*,end=9000) t,vector
02165       else
02166          read(iUnit,ioStat=ioStat,fmt=*,end=9000) t,scalar
02167          do i=1,nvar-1
02168             vector(:,i) = scalar(i)
02169          enddo
02170       endif
02171 
02172       if (iostat /= 0) then
02173          inquire(iUnit,name=ername)
02174          call report_file_read_error(ername)
02175       endif
02176 
02177       return
02178 9000  iseof = .true.
02179 
02180    end subroutine velocity_Boundary_read
02181 
02182 end module boundaryconditions
 All Classes Files Functions Variables Defines