Ignore:
Timestamp:
Mar 27, 2018 3:52:42 PM (3 years ago)
Author:
suehring
Message:

Nesting in RANS-LES and RANS-RANS mode enabled; synthetic turbulence generator at all lateral boundaries in nesting or non-cyclic forcing mode; revised Inifor initialization in nesting mode

File:
1 edited

Legend:

Unmodified
Added
Removed
  • palm/trunk/SOURCE/synthetic_turbulence_generator_mod.f90

    r2894 r2938  
    2525! -----------------
    2626! $Id$
     27! Apply turbulence generator at all non-cyclic lateral boundaries in case of
     28! realistic Inifor large-scale forcing or RANS-LES nesting
     29!
     30! 2936 2018-03-27 14:49:27Z suehring
    2731! variable named found has been introduced for checking if restart data was found,
    2832! reading of restart strings has been moved completely to read_restart_data_mod,
     
    101105
    102106    USE control_parameters,                                                    &
    103         ONLY:  initializing_actions, message_string,                           &
    104                syn_turb_gen
     107        ONLY:  initializing_actions, message_string, syn_turb_gen
    105108
    106109    USE cpulog,                                                                &
     
    108111
    109112    USE indices,                                                               &
    110         ONLY:  nbgp, nzb, nzt, nyng, nysg
     113        ONLY:  nbgp, nzb, nzt, nxl, nxlg, nxr, nxrg, nys, nyn, nyng, nysg
    111114
    112115    USE kinds
     
    117120
    118121    USE pegrid,                                                                &
    119         ONLY:  comm1dx, comm1dy, comm2d, id_inflow, ierr, myidx, pdims
     122        ONLY:  comm1dx, comm1dy, comm2d, ierr, myidx, myidy, pdims
    120123
    121124    USE transpose_indices,                                                     &
     
    132135    LOGICAL :: use_syn_turb_gen = .FALSE.           !< switch to use synthetic turbulence generator
    133136
    134     INTEGER(iwp) :: stg_type_yz        !< MPI type for full z range
    135     INTEGER(iwp) :: stg_type_yz_small  !< MPI type for small z range
    136     INTEGER(iwp) :: merg               !< maximum length scale (in gp)
    137     INTEGER(iwp) :: mergp              !< merg + nbgp
     137    INTEGER(iwp) ::  id_stg_left        !< left lateral boundary core id in case of turbulence generator 
     138    INTEGER(iwp) ::  id_stg_north       !< north lateral boundary core id in case of turbulence generator 
     139    INTEGER(iwp) ::  id_stg_right       !< right lateral boundary core id in case of turbulence generator 
     140    INTEGER(iwp) ::  id_stg_south       !< south lateral boundary core id in case of turbulence generator 
     141    INTEGER(iwp) ::  stg_type_xz        !< MPI type for full z range
     142    INTEGER(iwp) ::  stg_type_xz_small  !< MPI type for small z range
     143    INTEGER(iwp) ::  stg_type_yz        !< MPI type for full z range
     144    INTEGER(iwp) ::  stg_type_yz_small  !< MPI type for small z range
     145    INTEGER(iwp) ::  merg               !< maximum length scale (in gp)
     146    INTEGER(iwp) ::  mergp              !< merg + nbgp
     147    INTEGER(iwp) ::  nzb_x_stg          !<
     148    INTEGER(iwp) ::  nzt_x_stg          !<
     149    INTEGER(iwp) ::  nzb_y_stg          !<
     150    INTEGER(iwp) ::  nzt_y_stg          !<
    138151
    139152    REAL(wp) :: mc_factor    !< mass flux correction factor
    140153
    141     INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: displs      !< displacement for MPI_GATHERV
    142     INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: recv_count  !< receive count for MPI_GATHERV
    143     INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nuy         !< length scale of u in y direction (in gp)
    144     INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nuz         !< length scale of u in z direction (in gp)
    145     INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nvy         !< length scale of v in y direction (in gp)
    146     INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nvz         !< length scale of v in z direction (in gp)
    147     INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nwy         !< length scale of w in y direction (in gp)
    148     INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nwz         !< length scale of w in z direction (in gp)
     154    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: displs_xz      !< displacement for MPI_GATHERV
     155    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: recv_count_xz  !< receive count for MPI_GATHERV
     156    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: displs_yz      !< displacement for MPI_GATHERV
     157    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: recv_count_yz  !< receive count for MPI_GATHERV
     158    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nux            !< length scale of u in x direction (in gp)
     159    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nuy            !< length scale of u in y direction (in gp)
     160    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nuz            !< length scale of u in z direction (in gp)
     161    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nvx            !< length scale of v in x direction (in gp)
     162    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nvy            !< length scale of v in y direction (in gp)
     163    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nvz            !< length scale of v in z direction (in gp)
     164    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nwx            !< length scale of w in x direction (in gp)
     165    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nwy            !< length scale of w in y direction (in gp)
     166    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nwz            !< length scale of w in z direction (in gp)
    149167
    150168    INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: seed        !< seed of random number for rn-generator
     
    160178    REAL(wp), DIMENSION(:), ALLOCATABLE :: tw              !< Lagrangian time scale of w
    161179
     180    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bux           !< filter function for u in x direction
    162181    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: buy           !< filter function for u in y direction
    163182    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: buz           !< filter function for u in z direction
     183    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bvx           !< filter function for v in x direction
    164184    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bvy           !< filter function for v in y direction
    165185    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bvz           !< filter function for v in z direction
     186    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bwx           !< filter function for w in y direction
    166187    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bwy           !< filter function for w in y direction
    167188    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bwz           !< filter function for w in z direction
    168     REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fu            !< velocity seed for u
    169     REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fuo           !< velocity seed for u with new random number
    170     REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fv            !< velocity seed for v
    171     REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fvo           !< velocity seed for v with new random number
    172     REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fw            !< velocity seed for w
    173     REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fwo           !< velocity seed for w with new random number
     189    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fu_xz         !< velocity seed for u at xz plane
     190    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fuo_xz        !< velocity seed for u at xz plane with new random number
     191    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fu_yz         !< velocity seed for u at yz plane
     192    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fuo_yz        !< velocity seed for u at yz plane with new random number
     193    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fv_xz         !< velocity seed for v at xz plane
     194    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fvo_xz        !< velocity seed for v at xz plane with new random number
     195    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fv_yz         !< velocity seed for v at yz plane
     196    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fvo_yz        !< velocity seed for v at yz plane with new random number
     197    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fw_xz         !< velocity seed for w at xz plane
     198    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fwo_xz        !< velocity seed for w at xz plane with new random number
     199    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fw_yz         !< velocity seed for w at yz plane
     200    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fwo_yz        !< velocity seed for w at yz plane with new random number
    174201
    175202
     
    188215
    189216!
    190 !-- Generate velocity seeds
     217!-- Generate velocity seeds at south and north domain boundary
     218    INTERFACE stg_generate_seed_xz
     219       MODULE PROCEDURE stg_generate_seed_xz
     220    END INTERFACE stg_generate_seed_xz
     221!
     222!-- Generate velocity seeds at left and/or right domain boundary
    191223    INTERFACE stg_generate_seed_yz
    192224       MODULE PROCEDURE stg_generate_seed_yz
     
    240272!
    241273!-- Public variables
    242     PUBLIC  use_syn_turb_gen
     274    PUBLIC  id_stg_left, id_stg_north, id_stg_right, id_stg_south,             &
     275            use_syn_turb_gen
    243276
    244277
     
    255288
    256289    USE control_parameters,                                                    &
    257         ONLY:  bc_lr, bc_ns, turbulent_inflow
     290        ONLY:  bc_lr, bc_ns, forcing, nest_domain, rans_mode, turbulent_inflow
     291
     292    USE pmc_interface,                                                         &
     293        ONLY : rans_mode_parent
    258294
    259295
    260296    IMPLICIT NONE
    261297
     298    IF ( .NOT. use_syn_turb_gen  .AND.  .NOT. rans_mode  .AND.  forcing )  THEN
     299       message_string = 'Synthetic turbulence generator has to be applied ' // &
     300                        'when forcing is used and model operates in LES mode.'
     301       CALL message( 'stg_check_parameters', 'PA0000', 1, 2, 0, 6, 0 )
     302    ENDIF
     303
     304    IF ( .NOT. use_syn_turb_gen  .AND.  nest_domain                            &
     305         .AND. rans_mode_parent  .AND.  .NOT. rans_mode )  THEN
     306       message_string = 'Synthetic turbulence generator has to be applied ' // &
     307                        'when nesting is applied and parent operates in '  //  &
     308                        'RANS-mode but current child in LES mode.'
     309       CALL message( 'stg_check_parameters', 'PA0000', 1, 2, 0, 6, 0 )
     310    ENDIF
     311
    262312    IF ( use_syn_turb_gen )  THEN
    263313
    264        IF ( INDEX( initializing_actions, 'set_constant_profiles' ) == 0  .AND. &
    265             INDEX( initializing_actions, 'read_restart_data' ) == 0 )  THEN
    266           message_string = 'Using synthetic turbulence generator ' //          &
    267                            'requires &initializing_actions = '            //   &
    268                            '"set_constant_profiles" or "read_restart_data"'
    269           CALL message( 'stg_check_parameters', 'PA0015', 1, 2, 0, 6, 0 )
     314       IF ( .NOT. forcing  .AND.  .NOT. nest_domain )  THEN
     315
     316          IF ( INDEX( initializing_actions, 'set_constant_profiles' ) == 0     &
     317        .AND.  INDEX( initializing_actions, 'read_restart_data' ) == 0 )  THEN
     318             message_string = 'Using synthetic turbulence generator ' //       &
     319                              'requires &initializing_actions = '         //   &
     320                              '"set_constant_profiles" or "read_restart_data"'
     321             CALL message( 'stg_check_parameters', 'PA0015', 1, 2, 0, 6, 0 )
     322          ENDIF
     323
     324          IF ( bc_lr /= 'dirichlet/radiation' )  THEN
     325             message_string = 'Using synthetic turbulence generator ' //       &
     326                              'requires &bc_lr = "dirichlet/radiation"'
     327             CALL message( 'stg_check_parameters', 'PA0035', 1, 2, 0, 6, 0 )
     328          ENDIF
     329          IF ( bc_ns /= 'cyclic' )  THEN
     330             message_string = 'Using synthetic turbulence generator ' //       &
     331                              'requires &bc_ns = "cyclic"'
     332             CALL message( 'stg_check_parameters', 'PA0037', 1, 2, 0, 6, 0 )
     333          ENDIF
     334
    270335       ENDIF
    271336
    272        IF ( bc_lr /= 'dirichlet/radiation' )  THEN
    273           message_string = 'Using synthetic turbulence generator ' //          &
    274                            'requires &bc_lr = "dirichlet/radiation"'
    275           CALL message( 'stg_check_parameters', 'PA0035', 1, 2, 0, 6, 0 )
    276        ENDIF
    277        IF ( bc_ns /= 'cyclic' )  THEN
    278           message_string = 'Using synthetic turbulence generator ' //          &
    279                            'requires &bc_ns = "cyclic"'
    280           CALL message( 'stg_check_parameters', 'PA0037', 1, 2, 0, 6, 0 )
    281        ENDIF
    282337       IF ( turbulent_inflow )  THEN
    283338          message_string = 'Using synthetic turbulence generator ' //          &
    284                            'in combination &with turbulent_inflow = .T. ' //   &
    285                            'is not allowed'
     339                           'in combination &with turbulent_inflow = .T. '//    &
     340                              'is not allowed'
    286341          CALL message( 'stg_check_parameters', 'PA0039', 1, 2, 0, 6, 0 )
    287342       ENDIF
     
    330385
    331386    USE arrays_3d,                                                             &
    332         ONLY:  u_init, v_init
     387        ONLY:  ddzw, u_init, v_init, zu
    333388
    334389    USE control_parameters,                                                    &
    335         ONLY:  coupling_char, dz, e_init
     390        ONLY:  coupling_char, dz, e_init, forcing, nest_domain
    336391
    337392    USE grid_variables,                                                        &
    338         ONLY:  ddy
     393        ONLY:  ddx, ddy
     394
     395    USE indices,                                                               &
     396        ONLY:  nz
    339397
    340398
    341399    IMPLICIT NONE
     400
     401    LOGICAL ::  file_stg_exist = .FALSE. !< flag indication whether parameter file for Reynolds stress and length scales exist
    342402
    343403#if defined( __parallel )
     
    346406#endif
    347407
     408    INTEGER(iwp) :: i                        !> grid index in x-direction
    348409    INTEGER(iwp) :: j                        !> loop index
    349410    INTEGER(iwp) :: k                        !< index
    350411    INTEGER(iwp) :: newtype                  !< dummy MPI type
    351412    INTEGER(iwp) :: realsize                 !< size of REAL variables
     413    INTEGER(iwp) :: nnz                      !< increment used to determine processor decomposition of z-axis along x and y direction 
    352414    INTEGER(iwp) :: nseed                    !< dimension of random number seed
    353415    INTEGER(iwp) :: startseed = 1234567890   !< start seed for random number generator
     
    362424    REAL(wp) :: d21     !< vertical interpolation for a21
    363425    REAL(wp) :: d22     !< vertical interpolation for a22
     426    REAL(wp) :: dum_exp !< dummy variable used for exponential vertical decrease of turbulent length scales
    364427    REAL(wp) :: luy     !< length scale for u in y direction
    365428    REAL(wp) :: luz     !< length scale for u in z direction
     
    370433    REAL(wp) :: zz      !< height
    371434
     435    REAL(wp) :: length_scale_surface, r_ii_0, time_scale, length_scale_z
     436
    372437    REAL(wp),DIMENSION(nzb:nzt+1) :: r11  !< Reynolds parameter
    373438    REAL(wp),DIMENSION(nzb:nzt+1) :: r21  !< Reynolds parameter
     
    389454    ALLOCATE ( a11(nzb:nzt+1), a21(nzb:nzt+1), a22(nzb:nzt+1),                 &
    390455               a31(nzb:nzt+1), a32(nzb:nzt+1), a33(nzb:nzt+1),                 &
    391                nuy(nzb:nzt+1), nuz(nzb:nzt+1), nvy(nzb:nzt+1),                 &
    392                nvz(nzb:nzt+1), nwy(nzb:nzt+1), nwz(nzb:nzt+1),                 &
     456               nux(nzb:nzt+1), nuy(nzb:nzt+1), nuz(nzb:nzt+1),                 &
     457               nvx(nzb:nzt+1), nvy(nzb:nzt+1), nvz(nzb:nzt+1),                 &
     458               nwx(nzb:nzt+1), nwy(nzb:nzt+1), nwz(nzb:nzt+1),                 &
    393459               tu(nzb:nzt+1),  tv(nzb:nzt+1),  tw(nzb:nzt+1)   )
    394460
    395461#if defined( __parallel )
     462!
     463!-- Determine processor decomposition of z-axis along x- and y-direction
     464    nnz = nz / pdims(1)
     465    nzb_x_stg = 1 + myidx * nnz
     466    nzt_x_stg = ( myidx + 1 ) * nnz
     467
     468    IF ( MOD( nz , pdims(1) ) /= 0  .AND.  myidx == id_stg_right )             & 
     469       nzt_x_stg = myidx * nnz + MOD( nz , pdims(1) )
     470
     471    IF ( forcing  .OR.  nest_domain )  THEN
     472       nnz = nz / pdims(2)
     473       nzb_y_stg = 1 + myidy * nnz
     474       nzt_y_stg = ( myidy + 1 ) * nnz
     475
     476       IF ( MOD( nz , pdims(2) ) /= 0  .AND.  myidy == id_stg_north )          & 
     477          nzt_y_stg = myidy * nnz + MOD( nz , pdims(2) )
     478    ENDIF
     479
    396480!
    397481!-- Define MPI type used in stg_generate_seed_yz to gather vertical splitted
     
    399483    CALL MPI_TYPE_SIZE( MPI_REAL, realsize, ierr )
    400484    extent = 1 * realsize
    401 
    402     ! stg_type_yz: yz-slice with vertical bounds nzb:nzt+1
     485!
     486!-- Set-up MPI datatyp to involve all cores for turbulence generation at yz
     487!-- layer
     488!-- stg_type_yz: yz-slice with vertical bounds nzb:nzt+1
    403489    CALL MPI_TYPE_CREATE_SUBARRAY( 2, [nzt-nzb+2,nyng-nysg+1],                 &
    404490            [1,nyng-nysg+1], [0,0], MPI_ORDER_FORTRAN, MPI_REAL, newtype, ierr )
     
    407493    CALL MPI_TYPE_FREE( newtype, ierr )
    408494
    409     ! stg_type_yz_small: yz-slice with vertical bounds nzb_x:nzt_x+1
    410     CALL MPI_TYPE_CREATE_SUBARRAY( 2, [nzt_x-nzb_x+2,nyng-nysg+1],             &
     495    ! stg_type_yz_small: yz-slice with vertical bounds nzb_x_stg:nzt_x_stg+1
     496    CALL MPI_TYPE_CREATE_SUBARRAY( 2, [nzt_x_stg-nzb_x_stg+2,nyng-nysg+1],             &
    411497            [1,nyng-nysg+1], [0,0], MPI_ORDER_FORTRAN, MPI_REAL, newtype, ierr )
    412498    CALL MPI_TYPE_CREATE_RESIZED( newtype, tob, extent, stg_type_yz_small, ierr )
     
    415501
    416502    ! receive count and displacement for MPI_GATHERV in stg_generate_seed_yz
    417     ALLOCATE( recv_count(pdims(1)), displs(pdims(1)) )
    418 
    419     recv_count           = nzt_x-nzb_x + 1
    420     recv_count(pdims(1)) = recv_count(pdims(1)) + 1
     503    ALLOCATE( recv_count_yz(pdims(1)), displs_yz(pdims(1)) )
     504
     505    recv_count_yz           = nzt_x_stg-nzb_x_stg + 1
     506    recv_count_yz(pdims(1)) = recv_count_yz(pdims(1)) + 1
    421507
    422508    DO  j = 1, pdims(1)
    423        displs(j) = 0 + (nzt_x-nzb_x+1) * (j-1)
    424     ENDDO
     509       displs_yz(j) = 0 + (nzt_x_stg-nzb_x_stg+1) * (j-1)
     510    ENDDO
     511!
     512!-- Set-up MPI datatyp to involve all cores for turbulence generation at xz
     513!-- layer
     514!-- stg_type_xz: xz-slice with vertical bounds nzb:nzt+1
     515    IF ( forcing  .OR.  nest_domain)  THEN
     516       CALL MPI_TYPE_CREATE_SUBARRAY( 2, [nzt-nzb+2,nxrg-nxlg+1],                 &
     517               [1,nxrg-nxlg+1], [0,0], MPI_ORDER_FORTRAN, MPI_REAL, newtype, ierr )
     518       CALL MPI_TYPE_CREATE_RESIZED( newtype, tob, extent, stg_type_xz, ierr )
     519       CALL MPI_TYPE_COMMIT( stg_type_xz, ierr )
     520       CALL MPI_TYPE_FREE( newtype, ierr )
     521
     522       ! stg_type_yz_small: xz-slice with vertical bounds nzb_x_stg:nzt_x_stg+1
     523       CALL MPI_TYPE_CREATE_SUBARRAY( 2, [nzt_y_stg-nzb_y_stg+2,nxrg-nxlg+1],             &
     524               [1,nxrg-nxlg+1], [0,0], MPI_ORDER_FORTRAN, MPI_REAL, newtype, ierr )
     525       CALL MPI_TYPE_CREATE_RESIZED( newtype, tob, extent, stg_type_xz_small, ierr )
     526       CALL MPI_TYPE_COMMIT( stg_type_xz_small, ierr )
     527       CALL MPI_TYPE_FREE( newtype, ierr )
     528
     529       ! receive count and displacement for MPI_GATHERV in stg_generate_seed_yz
     530       ALLOCATE( recv_count_xz(pdims(2)), displs_xz(pdims(2)) )
     531
     532       recv_count_xz           = nzt_y_stg-nzb_y_stg + 1
     533       recv_count_xz(pdims(2)) = recv_count_xz(pdims(2)) + 1
     534
     535       DO  j = 1, pdims(2)
     536          displs_xz(j) = 0 + (nzt_y_stg-nzb_y_stg+1) * (j-1)
     537       ENDDO
     538
     539    ENDIF
     540
    425541#endif
    426 
    427542!
    428543!-- Define seed of random number
     
    435550    CALL RANDOM_SEED(put=seed)
    436551
    437 !
    438552!-- Read inflow profile
    439553!-- Height levels of profiles in input profile is as follows:
     
    441555!-- zw: lwy, lwz, tw, r31, r32, r33, d3
    442556!-- WARNING: zz is not used at the moment
    443     OPEN( 90, FILE='STG_PROFILES'//TRIM( coupling_char ), STATUS='OLD',        &
    444                    FORM='FORMATTED')
    445 
    446     ! Skip header
    447     READ( 90, * )
    448 
    449     DO  k = nzb, nzt+1
    450        READ( 90, * ) zz, luy, luz, tu(k), lvy, lvz, tv(k), lwy, lwz, tw(k),    &
    451                      r11(k), r21(k), r22(k), r31(k), r32(k), r33(k),           &
    452                      d1, d2, d3, d5
    453 
    454 !
    455 !--    Convert length scales from meter to number of grid points
    456        nuy(k) = INT( luy * ddy )
    457        nuz(k) = INT( luz / dz  )
    458        nvy(k) = INT( lvy * ddy )
    459        nvz(k) = INT( lvz / dz  )
    460        nwy(k) = INT( lwy * ddy )
    461        nwz(k) = INT( lwz / dz  )
    462 
    463 !
    464 !--    Save Mean inflow profiles
    465        IF ( TRIM( initializing_actions ) /= 'read_restart_data' ) THEN
    466           mean_inflow_profiles(k,1) = d1
    467           mean_inflow_profiles(k,2) = d2
    468          !  mean_inflow_profiles(k,4) = d4
    469           mean_inflow_profiles(k,5) = d5
    470        ENDIF
    471     ENDDO
    472 
    473     CLOSE( 90 )
    474 
    475 !
    476 !--    Assign initial profiles
    477     u_init = mean_inflow_profiles(:,1)
    478     v_init = mean_inflow_profiles(:,2)
    479    !  pt_init = mean_inflow_profiles(:,4)
    480     e_init = MAXVAL( mean_inflow_profiles(:,5) )
    481 
     557    INQUIRE( FILE = 'STG_PROFILES' // TRIM( coupling_char ),                   &
     558             EXIST = file_stg_exist  )
     559
     560    IF ( file_stg_exist )  THEN
     561
     562       OPEN( 90, FILE='STG_PROFILES'//TRIM( coupling_char ), STATUS='OLD',     &
     563                      FORM='FORMATTED')
     564!
     565!--    Skip header
     566       READ( 90, * )
     567
     568       DO  k = nzb, nzt+1
     569          READ( 90, * ) zz, luy, luz, tu(k), lvy, lvz, tv(k), lwy, lwz, tw(k), &
     570                        r11(k), r21(k), r22(k), r31(k), r32(k), r33(k),        &
     571                        d1, d2, d3, d5
     572
     573!
     574!--       Convert length scales from meter to number of grid points
     575          nuy(k) = INT( luy * ddy )
     576          nuz(k) = INT( luz / dz  )
     577          nvy(k) = INT( lvy * ddy )
     578          nvz(k) = INT( lvz / dz  )
     579          nwy(k) = INT( lwy * ddy )
     580          nwz(k) = INT( lwz / dz  )
     581!
     582!--       Workaround, assume isotropic turbulence
     583          nwx(k) = nwy(k)
     584          nvx(k) = nvy(k)
     585          nux(k) = nuy(k)
     586!
     587!--       Save Mean inflow profiles
     588          IF ( TRIM( initializing_actions ) /= 'read_restart_data' ) THEN
     589             mean_inflow_profiles(k,1) = d1
     590             mean_inflow_profiles(k,2) = d2
     591            !  mean_inflow_profiles(k,4) = d4
     592             mean_inflow_profiles(k,5) = d5
     593          ENDIF
     594       ENDDO
     595
     596       CLOSE( 90 )
     597   
     598    ELSE
     599!
     600!--    Set-up defaul length scales. Assume exponentially decreasing length
     601!--    scales and isotropic turbulence.
     602!--    Typical length (time) scales of 100 m (s) should be a goog compromise
     603!--    between all stratrifications. Near-surface variances are fixed to
     604!--    0.1 m2/s2, vertical fluxes are one order of magnitude smaller.
     605!--    Vertical fluxes 
     606       length_scale_surface = 100.0_wp
     607       r_ii_0               = 0.1_wp
     608       time_scale           = 100.0_wp
     609       DO  k = nzb+1, nzt+1
     610          dum_exp        = MERGE( -zu(k) / ( 0.3* zu(nzt) ),                   &
     611                                  0.0_wp,                                      &
     612                                  zu(k) > 0.3 * zu(nzt)                        &
     613                                )
     614          length_scale_z = length_scale_surface * EXP( dum_exp )
     615
     616          nux(k) = MAX( INT( length_scale_z * ddx     ), 1 )
     617          nuy(k) = MAX( INT( length_scale_z * ddy     ), 1 )
     618          nuz(k) = MAX( INT( length_scale_z * ddzw(k) ), 1 )
     619          nvx(k) = MAX( INT( length_scale_z * ddx     ), 1 )
     620          nvy(k) = MAX( INT( length_scale_z * ddy     ), 1 )
     621          nvz(k) = MAX( INT( length_scale_z * ddzw(k) ), 1 )
     622          nwx(k) = MAX( INT( length_scale_z * ddx     ), 1 )
     623          nwy(k) = MAX( INT( length_scale_z * ddy     ), 1 )
     624          nwz(k) = MAX( INT( length_scale_z * ddzw(k) ), 1 )
     625
     626          r11(k) = r_ii_0 * EXP( dum_exp )
     627          r22(k) = r_ii_0 * EXP( dum_exp )
     628          r33(k) = r_ii_0 * EXP( dum_exp )
     629
     630          r21(k) = 0.1_wp * r_ii_0 * EXP( dum_exp )
     631          r31(k) = 0.1_wp * r_ii_0 * EXP( dum_exp )
     632          r32(k) = 0.1_wp * r_ii_0 * EXP( dum_exp )
     633
     634          tu(k)  = time_scale
     635          tv(k)  = time_scale
     636          tw(k)  = time_scale
     637
     638       ENDDO
     639       nux(nzb) = nux(nzb+1)
     640       nuy(nzb) = nuy(nzb+1)
     641       nuz(nzb) = nuz(nzb+1)
     642       nvx(nzb) = nvx(nzb+1)
     643       nvy(nzb) = nvy(nzb+1)
     644       nvz(nzb) = nvz(nzb+1)
     645       nwx(nzb) = nwx(nzb+1)
     646       nwy(nzb) = nwy(nzb+1)
     647       nwz(nzb) = nwz(nzb+1)
     648
     649       r11(nzb) = r11(nzb+1)
     650       r22(nzb) = r22(nzb+1)
     651       r33(nzb) = r33(nzb+1)
     652
     653       r21(nzb) = r11(nzb+1)
     654       r31(nzb) = r31(nzb+1)
     655       r32(nzb) = r32(nzb+1)
     656
     657       tu(nzb)  = time_scale
     658       tv(nzb)  = time_scale
     659       tw(nzb)  = time_scale
     660
     661    ENDIF
     662
     663!
     664!-- Assign initial profiles
     665    IF ( .NOT. forcing  .AND.  .NOT.  nest_domain )  THEN
     666       u_init = mean_inflow_profiles(:,1)
     667       v_init = mean_inflow_profiles(:,2)
     668      !pt_init = mean_inflow_profiles(:,4)
     669       e_init = MAXVAL( mean_inflow_profiles(:,5) )
     670    ENDIF
    482671!
    483672!-- Calculate coefficient matrix from Reynolds stress tensor (Lund rotation)
     
    534723
    535724    ENDDO
    536 
    537725!
    538726!-- Define the size of the filter functions and allocate them.
     
    541729    ! arrays must be large enough to cover the largest length scale
    542730    DO  k = nzb, nzt+1
    543        j = MAX( ABS(nuy(k)), ABS(nuz(k)), &
    544                 ABS(nvy(k)), ABS(nvz(k)), &
    545                 ABS(nwy(k)), ABS(nwz(k))  )
     731       j = MAX( ABS(nux(k)), ABS(nuy(k)), ABS(nuz(k)), &
     732                ABS(nvx(k)), ABS(nvy(k)), ABS(nvz(k)), &
     733                ABS(nwx(k)), ABS(nwy(k)), ABS(nwz(k))  )
    546734       IF ( j > merg )  merg = j
    547735    ENDDO
     
    550738    mergp = merg + nbgp
    551739
    552     ALLOCATE ( buy(-merg:merg,nzb:nzt+1), buz(-merg:merg,nzb:nzt+1), &
    553                bvy(-merg:merg,nzb:nzt+1), bvz(-merg:merg,nzb:nzt+1), &
    554                bwy(-merg:merg,nzb:nzt+1), bwz(-merg:merg,nzb:nzt+1)  )
    555 
    556 !
    557 !-- Allocate velocity seeds
    558     ALLOCATE ( fu( nzb:nzt+1,nysg:nyng), fuo(nzb:nzt+1,nysg:nyng), &
    559                fv( nzb:nzt+1,nysg:nyng), fvo(nzb:nzt+1,nysg:nyng), &
    560                fw( nzb:nzt+1,nysg:nyng), fwo(nzb:nzt+1,nysg:nyng)  )
    561 
    562     fu  = 0._wp
    563     fuo = 0._wp
    564     fv  = 0._wp
    565     fvo = 0._wp
    566     fw  = 0._wp
    567     fwo = 0._wp
     740    ALLOCATE ( bux(-merg:merg,nzb:nzt+1),                                      &
     741               buy(-merg:merg,nzb:nzt+1),                                      &
     742               buz(-merg:merg,nzb:nzt+1),                                      &
     743               bvx(-merg:merg,nzb:nzt+1),                                      &
     744               bvy(-merg:merg,nzb:nzt+1),                                      &
     745               bvz(-merg:merg,nzb:nzt+1),                                      &
     746               bwx(-merg:merg,nzb:nzt+1),                                      &
     747               bwy(-merg:merg,nzb:nzt+1),                                      &
     748               bwz(-merg:merg,nzb:nzt+1)  )
     749
     750!
     751!-- Allocate velocity seeds for turbulence at xz-layer
     752    ALLOCATE ( fu_xz( nzb:nzt+1,nxlg:nxrg), fuo_xz(nzb:nzt+1,nxlg:nxrg),       &
     753               fv_xz( nzb:nzt+1,nxlg:nxrg), fvo_xz(nzb:nzt+1,nxlg:nxrg),       &
     754               fw_xz( nzb:nzt+1,nxlg:nxrg), fwo_xz(nzb:nzt+1,nxlg:nxrg)  )
     755
     756!
     757!-- Allocate velocity seeds for turbulence at yz-layer
     758    ALLOCATE ( fu_yz( nzb:nzt+1,nysg:nyng), fuo_yz(nzb:nzt+1,nysg:nyng),       &
     759               fv_yz( nzb:nzt+1,nysg:nyng), fvo_yz(nzb:nzt+1,nysg:nyng),       &
     760               fw_yz( nzb:nzt+1,nysg:nyng), fwo_yz(nzb:nzt+1,nysg:nyng)  )
     761
     762    fu_xz  = 0.0_wp
     763    fuo_xz = 0.0_wp
     764    fv_xz  = 0.0_wp
     765    fvo_xz = 0.0_wp
     766    fw_xz  = 0.0_wp
     767    fwo_xz = 0.0_wp
     768
     769    fu_yz  = 0.0_wp
     770    fuo_yz = 0.0_wp
     771    fv_yz  = 0.0_wp
     772    fvo_yz = 0.0_wp
     773    fw_yz  = 0.0_wp
     774    fwo_yz = 0.0_wp
    568775
    569776!
    570777!-- Create filter functions
     778    CALL stg_filter_func( nux, bux ) !filter ux
    571779    CALL stg_filter_func( nuy, buy ) !filter uy
    572780    CALL stg_filter_func( nuz, buz ) !filter uz
     781    CALL stg_filter_func( nvx, bvx ) !filter vx
    573782    CALL stg_filter_func( nvy, bvy ) !filter vy
    574783    CALL stg_filter_func( nvz, bvz ) !filter vz
     784    CALL stg_filter_func( nwx, bwx ) !filter wx
    575785    CALL stg_filter_func( nwy, bwy ) !filter wy
    576786    CALL stg_filter_func( nwz, bwz ) !filter wz
     
    581791
    582792!
    583 !--    In case of restart, calculate velocity seeds fu, fv, fw from former
    584 !      time step.
    585 !      Bug: fu, fv, fw are different in those heights where a11, a22, a33
    586 !           are 0 compared to the prerun. This is mostly for k=nzt+1.
     793!-- In case of restart, calculate velocity seeds fu, fv, fw from former
     794!   time step.
     795!   Bug: fu, fv, fw are different in those heights where a11, a22, a33
     796!        are 0 compared to the prerun. This is mostly for k=nzt+1.
    587797    IF ( TRIM( initializing_actions ) == 'read_restart_data' )  THEN
    588        IF ( myidx == id_inflow )  THEN
     798       IF ( myidx == id_stg_left  .OR.  myidx == id_stg_right )  THEN
     799
     800          IF ( myidx == id_stg_left  )  i = -1
     801          IF ( myidx == id_stg_right )  i = nxr+1
     802
    589803          DO  j = nysg, nyng
    590804             DO  k = nzb, nzt+1
    591805
    592806                IF  ( a11(k) .NE. 0._wp ) THEN
    593                 fu(k,j) = ( u(k,j,-1) / mc_factor -                    &
    594                             mean_inflow_profiles(k,1) ) / a11(k)
     807                   fu_yz(k,j) = ( u(k,j,i) / mc_factor - u_init(k) ) / a11(k)
    595808                ELSE
    596                    fu(k,j) = 0._wp
     809                   fu_yz(k,j) = 0._wp
    597810                ENDIF
    598811
    599812                IF  ( a22(k) .NE. 0._wp ) THEN
    600                 fv(k,j) = ( v(k,j,-1) / mc_factor - a21(k) * fu(k,j) - &
    601                             mean_inflow_profiles(k,2) ) / a22(k)
     813                   fv_yz(k,j) = ( v(k,j,i) / mc_factor - a21(k) * fu_yz(k,j) - &
     814                               v_init(k) ) / a22(k)
    602815                ELSE
    603                    fv(k,j) = 0._wp
     816                   fv_yz(k,j) = 0._wp
    604817                ENDIF
    605818
    606819                IF  ( a33(k) .NE. 0._wp ) THEN
    607                 fw(k,j) = ( w(k,j,-1) / mc_factor - a31(k) * fu(k,j) - &
    608                             a32(k) * fv(k,j) ) / a33(k)
     820                   fw_yz(k,j) = ( w(k,j,i) / mc_factor - a31(k) * fu_yz(k,j) - &
     821                               a32(k) * fv_yz(k,j) ) / a33(k)
    609822                ELSE
    610                    fw = 0._wp
     823                   fw_yz = 0._wp
    611824                ENDIF
    612825
     
    759972    IMPLICIT NONE
    760973
    761 
    762974    CALL wrd_write_string( 'mc_factor' )
    763975    WRITE ( 14 )  mc_factor
     
    785997
    786998    USE control_parameters,                                                    &
    787         ONLY:  dt_3d, intermediate_timestep_count, simulated_time,             &
    788                volume_flow_initial
     999        ONLY:  dt_3d, forcing, intermediate_timestep_count,  nest_domain,      &
     1000               simulated_time, volume_flow_initial
     1001
     1002    USE grid_variables,                                                        &
     1003        ONLY:  dx, dy
    7891004
    7901005    USE indices,                                                               &
    791         ONLY:  nyn, nys
     1006        ONLY:  wall_flags_0
    7921007
    7931008    USE statistics,                                                            &
     
    7971012    IMPLICIT NONE
    7981013
     1014    INTEGER(iwp) :: i           !< grid index in x-direction
    7991015    INTEGER(iwp) :: j           !< loop index in y-direction
    8001016    INTEGER(iwp) :: k           !< loop index in z-direction
     
    8021018    REAL(wp) :: dt_stg          !< wheighted subtimestep
    8031019    REAL(wp) :: mc_factor_l     !< local mass flux correction factor
    804 
    805     REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,5,nbgp) :: inflow_dist !< disturbance for inflow profiles
     1020    REAL(wp) :: volume_flow     !< mass flux through lateral boundary
     1021    REAL(wp) :: volume_flow_l   !< local mass flux through lateral boundary
     1022
     1023    REAL(wp), DIMENSION(nzb:nzt+1,nxlg:nxrg,5) :: dist_xz !< imposed disturbances at north/south boundary
     1024    REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,5) :: dist_yz !< imposed disturbances at left/right boundary
    8061025
    8071026
     
    8151034!-- Initial value of fu, fv, fw
    8161035    IF ( simulated_time == 0.0_wp .AND. .NOT. velocity_seed_initialized )  THEN
    817        CALL stg_generate_seed_yz( nuy, nuz, buy, buz, fu )
    818        CALL stg_generate_seed_yz( nvy, nvz, bvy, bvz, fv )
    819        CALL stg_generate_seed_yz( nwy, nwz, bwy, bwz, fw )
     1036       CALL stg_generate_seed_yz( nuy, nuz, buy, buz, fu_yz, id_stg_left )
     1037       CALL stg_generate_seed_yz( nvy, nvz, bvy, bvz, fv_yz, id_stg_left )
     1038       CALL stg_generate_seed_yz( nwy, nwz, bwy, bwz, fw_yz, id_stg_left )
     1039
     1040       IF ( forcing  .OR.  nest_domain )  THEN
     1041!
     1042!--       Generate turbulence at right boundary
     1043          CALL stg_generate_seed_yz( nuy, nuz, buy, buz, fu_yz, id_stg_right )
     1044          CALL stg_generate_seed_yz( nvy, nvz, bvy, bvz, fv_yz, id_stg_right )
     1045          CALL stg_generate_seed_yz( nwy, nwz, bwy, bwz, fw_yz, id_stg_right )
     1046!
     1047!--       Generate turbulence at north boundary
     1048          CALL stg_generate_seed_xz( nux, nuz, bux, buz, fu_xz, id_stg_north )
     1049          CALL stg_generate_seed_xz( nvx, nvz, bvx, bvz, fv_xz, id_stg_north )
     1050          CALL stg_generate_seed_xz( nwx, nwz, bwx, bwz, fw_xz, id_stg_north )
     1051!
     1052!--       Generate turbulence at south boundary
     1053          CALL stg_generate_seed_xz( nux, nuz, bux, buz, fu_xz, id_stg_south )
     1054          CALL stg_generate_seed_xz( nvx, nvz, bvx, bvz, fv_xz, id_stg_south )
     1055          CALL stg_generate_seed_xz( nwx, nwz, bwx, bwz, fw_xz, id_stg_south )
     1056       ENDIF
    8201057       velocity_seed_initialized = .TRUE.
    8211058    ENDIF
    8221059!
    8231060!-- New set of fu, fv, fw
    824     CALL stg_generate_seed_yz( nuy, nuz, buy, buz, fuo )
    825     CALL stg_generate_seed_yz( nvy, nvz, bvy, bvz, fvo )
    826     CALL stg_generate_seed_yz( nwy, nwz, bwy, bwz, fwo )
    827 
    828     IF ( myidx == id_inflow )  THEN
     1061    CALL stg_generate_seed_yz( nuy, nuz, buy, buz, fuo_yz, id_stg_left )
     1062    CALL stg_generate_seed_yz( nvy, nvz, bvy, bvz, fvo_yz, id_stg_left )
     1063    CALL stg_generate_seed_yz( nwy, nwz, bwy, bwz, fwo_yz, id_stg_left )
     1064
     1065    IF ( forcing  .OR.  nest_domain )  THEN
     1066!
     1067!--       Generate turbulence at right boundary
     1068          CALL stg_generate_seed_yz( nuy, nuz, buy, buz, fuo_yz, id_stg_right )
     1069          CALL stg_generate_seed_yz( nvy, nvz, bvy, bvz, fvo_yz, id_stg_right )
     1070          CALL stg_generate_seed_yz( nwy, nwz, bwy, bwz, fwo_yz, id_stg_right )
     1071!
     1072!--       Generate turbulence at north boundary
     1073          CALL stg_generate_seed_xz( nux, nuz, bux, buz, fuo_xz, id_stg_north )
     1074          CALL stg_generate_seed_xz( nvx, nvz, bvx, bvz, fvo_xz, id_stg_north )
     1075          CALL stg_generate_seed_xz( nwx, nwz, bwx, bwz, fwo_xz, id_stg_north )
     1076!
     1077!--       Generate turbulence at south boundary
     1078          CALL stg_generate_seed_xz( nux, nuz, bux, buz, fuo_xz, id_stg_south )
     1079          CALL stg_generate_seed_xz( nvx, nvz, bvx, bvz, fvo_xz, id_stg_south )
     1080          CALL stg_generate_seed_xz( nwx, nwz, bwx, bwz, fwo_xz, id_stg_south )
     1081    ENDIF
     1082!
     1083!-- Turbulence generation at left and or right boundary
     1084    IF ( myidx == id_stg_left  .OR.  myidx == id_stg_right )  THEN
    8291085
    8301086       DO  j = nysg, nyng
     
    8331089!--          Update fu, fv, fw following Eq. 14 of Xie and Castro (2008)
    8341090             IF ( tu(k) == 0.0_wp )  THEN
    835                 fu(k,j) = fuo(k,j)
     1091                fu_yz(k,j) = fuo_yz(k,j)
    8361092             ELSE
    837                 fu(k,j) = fu(k,j) * EXP( -pi * dt_stg * 0.5_wp / tu(k) ) +     &
    838                          fuo(k,j) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tu(k) ) )
     1093                fu_yz(k,j) = fu_yz(k,j) * EXP( -pi * dt_stg * 0.5_wp / tu(k) ) +     &
     1094                         fuo_yz(k,j) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tu(k) ) )
    8391095             ENDIF
    8401096
    8411097             IF ( tv(k) == 0.0_wp )  THEN
    842                 fv(k,j) = fvo(k,j)
     1098                fv_yz(k,j) = fvo_yz(k,j)
    8431099             ELSE
    844                 fv(k,j) = fv(k,j) * EXP( -pi * dt_stg * 0.5_wp / tv(k) ) +     &
    845                          fvo(k,j) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tv(k) ) )
     1100                fv_yz(k,j) = fv_yz(k,j) * EXP( -pi * dt_stg * 0.5_wp / tv(k) ) +     &
     1101                         fvo_yz(k,j) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tv(k) ) )
    8461102             ENDIF
    8471103
    8481104             IF ( tw(k) == 0.0_wp )  THEN
    849                 fw(k,j) = fwo(k,j)
     1105                fw_yz(k,j) = fwo_yz(k,j)
    8501106             ELSE
    851                 fw(k,j) = fw(k,j) * EXP( -pi * dt_stg * 0.5_wp / tw(k) ) +     &
    852                          fwo(k,j) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tw(k) ) )
     1107                fw_yz(k,j) = fw_yz(k,j) * EXP( -pi * dt_stg * 0.5_wp / tw(k) ) +     &
     1108                         fwo_yz(k,j) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tw(k) ) )
    8531109             ENDIF
    8541110!
     
    8561112!--          Additional factors are added to improve the variance of v and w
    8571113             IF( k == 0 )  THEN
    858                 inflow_dist(k,j,1,1) = 0.0_wp
    859                 inflow_dist(k,j,2,1) = 0.0_wp
    860                 inflow_dist(k,j,3,1) = 0.0_wp
    861                 inflow_dist(k,j,4,1) = 0.0_wp
    862                 inflow_dist(k,j,5,1) = 0.0_wp
     1114                dist_yz(k,j,1) = 0.0_wp
     1115                dist_yz(k,j,2) = 0.0_wp
     1116                dist_yz(k,j,3) = 0.0_wp
     1117!                 dist_yz(k,j,4) = 0.0_wp
     1118!                 dist_yz(k,j,5) = 0.0_wp
    8631119             ELSE
    864                 inflow_dist(k,j,1,1) = a11(k) * fu(k,j)
     1120                dist_yz(k,j,1) = a11(k) * fu_yz(k,j)
    8651121                !experimental test of 1.2
    866                 inflow_dist(k,j,2,1) = ( SQRT( a22(k) / MAXVAL(a22) )          &
     1122                dist_yz(k,j,2) = ( SQRT( a22(k) / MAXVAL(a22) )                   &
    8671123                                         * 1.2_wp )                            &
    868                                        * (   a21(k) * fu(k,j)                  &
    869                                            + a22(k) * fv(k,j) )
    870                 inflow_dist(k,j,3,1) = ( SQRT(a33(k) / MAXVAL(a33) )           &
     1124                                       * (   a21(k) * fu_yz(k,j)                  &
     1125                                           + a22(k) * fv_yz(k,j) )
     1126                dist_yz(k,j,3) = ( SQRT(a33(k) / MAXVAL(a33) )                    &
    8711127                                         * 1.3_wp )                            &
    872                                        * (   a31(k) * fu(k,j)                  &
    873                                            + a32(k) * fv(k,j)                  &
    874                                            + a33(k) * fw(k,j) )
     1128                                       * (   a31(k) * fu_yz(k,j)                  &
     1129                                           + a32(k) * fv_yz(k,j)                  &
     1130                                           + a33(k) * fw_yz(k,j) )
    8751131                ! Calculation for pt and e not yet implemented
    876                 inflow_dist(k,j,4,1) = 0.0_wp
    877                 inflow_dist(k,j,5,1) = 0.0_wp
     1132!                 dist_yz(k,j,4) = 0.0_wp
     1133!                 dist_yz(k,j,5) = 0.0_wp
    8781134             ENDIF
    8791135
     
    8851141!--    This correction factor insures that the mass flux is preserved at the
    8861142!--    inflow boundary
    887        mc_factor_l = 0.0_wp
    888        mc_factor   = 0.0_wp
    889        DO  j = nys, nyn
     1143       IF ( .NOT. forcing  .AND.  .NOT. nest_domain )  THEN
     1144          mc_factor_l = 0.0_wp
     1145          mc_factor   = 0.0_wp
     1146          DO  j = nys, nyn
     1147             DO  k = nzb+1, nzt
     1148                mc_factor_l = mc_factor_l + dzw(k)  *                          &
     1149                              ( mean_inflow_profiles(k,1) + dist_yz(k,j,1) )
     1150             ENDDO
     1151          ENDDO
     1152
     1153#if defined( __parallel )
     1154          CALL MPI_ALLREDUCE( mc_factor_l, mc_factor,  &
     1155                              1, MPI_REAL, MPI_SUM, comm1dy, ierr )
     1156#else
     1157          mc_factor = mc_factor_l
     1158#endif
     1159
     1160          mc_factor = volume_flow_initial(1) / mc_factor
     1161
     1162!
     1163!--       Add disturbance at the inflow
     1164          DO  j = nysg, nyng
     1165             DO  k = nzb, nzt+1
     1166                 u(k,j,-nbgp+1:0) = ( mean_inflow_profiles(k,1) +              &
     1167                                      dist_yz(k,j,1)             ) * mc_factor
     1168                 v(k,j,-nbgp:-1)  = ( mean_inflow_profiles(k,2) +              &
     1169                                      dist_yz(k,j,2)             ) * mc_factor
     1170                 w(k,j,-nbgp:-1)  =   dist_yz(k,j,3)               * mc_factor
     1171             ENDDO
     1172          ENDDO
     1173
     1174       ELSE
     1175!
     1176!--       First, calculate volume flow at yz boundary
     1177          IF ( myidx == id_stg_left  )  i = nxl
     1178          IF ( myidx == id_stg_right )  i = nxr+1
     1179
     1180          volume_flow_l = 0.0_wp
     1181          volume_flow   = 0.0_wp
     1182          mc_factor_l   = 0.0_wp
     1183          mc_factor     = 0.0_wp
     1184          DO  j = nys, nyn
     1185             DO  k = nzb+1, nzt
     1186                volume_flow_l = volume_flow_l + u(k,j,i) * dzw(k) * dy         &
     1187                                     * MERGE( 1.0_wp, 0.0_wp,                  &   
     1188                                              BTEST( wall_flags_0(k,j,i), 1 ) )
     1189
     1190                mc_factor_l = mc_factor_l     + ( u(k,j,i) + dist_yz(k,j,1) )  &
     1191                                                         * dzw(k) * dy         &
     1192                                     * MERGE( 1.0_wp, 0.0_wp,                  &   
     1193                                              BTEST( wall_flags_0(k,j,i), 1 ) )
     1194             ENDDO
     1195          ENDDO
     1196#if defined( __parallel )
     1197          CALL MPI_ALLREDUCE( volume_flow_l, volume_flow,                      &
     1198                              1, MPI_REAL, MPI_SUM, comm1dy, ierr )
     1199          CALL MPI_ALLREDUCE( mc_factor_l, mc_factor,                          &
     1200                              1, MPI_REAL, MPI_SUM, comm1dy, ierr )
     1201#else
     1202          volume_flow = volume_flow_l
     1203          mc_factor   = mc_factor_l
     1204#endif
     1205
     1206          mc_factor = volume_flow / mc_factor
     1207
     1208!
     1209!--       Add disturbances
     1210          IF ( myidx == id_stg_left  )  THEN
     1211
     1212             DO  j = nysg, nyng
     1213                DO  k = nzb, nzt+1
     1214                   u(k,j,-nbgp+1:0) = ( u(k,j,-nbgp+1:0) + dist_yz(k,j,1) )    &
     1215                                        * mc_factor
     1216                   v(k,j,-nbgp:-1)  = ( v(k,j,-nbgp:-1)  + dist_yz(k,j,2)  )   &
     1217                                        * mc_factor
     1218                   w(k,j,-nbgp:-1)  = ( w(k,j,-nbgp:-1)  + dist_yz(k,j,3)  )   &
     1219                                        * mc_factor
     1220                ENDDO
     1221             ENDDO
     1222          ENDIF
     1223          IF ( myidx == id_stg_right  )  THEN
     1224
     1225             DO  j = nysg, nyng
     1226                DO  k = nzb, nzt+1
     1227                   u(k,j,nxr+1:nxr+nbgp) = ( u(k,j,nxr+1:nxr+nbgp) +           &
     1228                                             dist_yz(k,j,1) ) * mc_factor
     1229                   v(k,j,nxr+1:nxr+nbgp) = ( v(k,j,nxr+1:nxr+nbgp) +           &
     1230                                             dist_yz(k,j,2) ) * mc_factor
     1231                   w(k,j,nxr+1:nxr+nbgp) = ( w(k,j,nxr+1:nxr+nbgp) +           &
     1232                                             dist_yz(k,j,3) ) * mc_factor
     1233                ENDDO
     1234             ENDDO
     1235          ENDIF
     1236       ENDIF
     1237
     1238    ENDIF
     1239!
     1240!-- Turbulence generation at north and south boundary
     1241    IF ( myidy == id_stg_north  .OR.  myidy == id_stg_south )  THEN
     1242
     1243       DO  i = nxlg, nxrg
     1244          DO  k = nzb, nzt + 1
     1245!
     1246!--          Update fu, fv, fw following Eq. 14 of Xie and Castro (2008)
     1247             IF ( tu(k) == 0.0_wp )  THEN
     1248                fu_xz(k,i) = fuo_xz(k,i)
     1249             ELSE
     1250                fu_xz(k,i) = fu_xz(k,i) * EXP( -pi * dt_stg * 0.5_wp / tu(k) ) +     &
     1251                         fuo_xz(k,i) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tu(k) ) )
     1252             ENDIF
     1253
     1254             IF ( tv(k) == 0.0_wp )  THEN
     1255                fv_xz(k,i) = fvo_xz(k,i)
     1256             ELSE
     1257                fv_xz(k,i) = fv_xz(k,i) * EXP( -pi * dt_stg * 0.5_wp / tv(k) ) +     &
     1258                         fvo_xz(k,i) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tv(k) ) )
     1259             ENDIF
     1260
     1261             IF ( tw(k) == 0.0_wp )  THEN
     1262                fw_xz(k,i) = fwo_xz(k,i)
     1263             ELSE
     1264                fw_xz(k,i) = fw_xz(k,i) * EXP( -pi * dt_stg * 0.5_wp / tw(k) ) +     &
     1265                         fwo_xz(k,i) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tw(k) ) )
     1266             ENDIF
     1267!
     1268!--          Lund rotation following Eq. 17 in Xie and Castro (2008).
     1269!--          Additional factors are added to improve the variance of v and w
     1270             IF( k == 0 )  THEN
     1271                dist_xz(k,i,1) = 0.0_wp
     1272                dist_xz(k,i,2) = 0.0_wp
     1273                dist_xz(k,i,3) = 0.0_wp
     1274
     1275             ELSE
     1276                dist_xz(k,i,1) = a11(k) * fu_xz(k,i)
     1277                !experimental test of 1.2
     1278                dist_xz(k,i,2) = ( SQRT( a22(k) / MAXVAL(a22) )                &
     1279                                         * 1.2_wp )                            &
     1280                                       * (   a21(k) * fu_xz(k,i)               &
     1281                                           + a22(k) * fv_xz(k,i) )
     1282                dist_xz(k,i,3) = ( SQRT(a33(k) / MAXVAL(a33) )                 &
     1283                                         * 1.3_wp )                            &
     1284                                       * (   a31(k) * fu_xz(k,i)               &
     1285                                           + a32(k) * fv_xz(k,i)               &
     1286                                           + a33(k) * fw_xz(k,i) )
     1287             ENDIF
     1288
     1289          ENDDO
     1290       ENDDO
     1291!
     1292!--    Mass flux correction following Kim et al. (2013)
     1293!--    This correction factor insures that the mass flux is preserved at the
     1294!--    inflow boundary.
     1295!--    First, calculate volume flow at xz boundary
     1296       IF ( myidy == id_stg_south  ) j = nys
     1297       IF ( myidy == id_stg_north )  j = nyn+1
     1298
     1299       volume_flow_l = 0.0_wp
     1300       volume_flow   = 0.0_wp
     1301       mc_factor_l   = 0.0_wp
     1302       mc_factor     = 0.0_wp
     1303       DO  i = nxl, nxr
    8901304          DO  k = nzb+1, nzt
    891              mc_factor_l = mc_factor_l + dzw(k)  *                             &
    892                            ( mean_inflow_profiles(k,1) + inflow_dist(k,j,1,1) )
     1305             volume_flow_l = volume_flow_l + v(k,j,i) * dzw(k) * dx         &
     1306                                  * MERGE( 1.0_wp, 0.0_wp,                  &   
     1307                                           BTEST( wall_flags_0(k,j,i), 2 ) )
     1308
     1309             mc_factor_l = mc_factor_l     + ( v(k,j,i) + dist_xz(k,i,2) )  &
     1310                                                      * dzw(k) * dx         &
     1311                                  * MERGE( 1.0_wp, 0.0_wp,                  &   
     1312                                           BTEST( wall_flags_0(k,j,i), 2 ) )
    8931313          ENDDO
    8941314       ENDDO
    895 
    8961315#if defined( __parallel )
    897        CALL MPI_ALLREDUCE( mc_factor_l, mc_factor,  &
    898                            1, MPI_REAL, MPI_SUM, comm1dy, ierr )
     1316       CALL MPI_ALLREDUCE( volume_flow_l, volume_flow,                      &
     1317                           1, MPI_REAL, MPI_SUM, comm1dx, ierr )
     1318       CALL MPI_ALLREDUCE( mc_factor_l, mc_factor,                          &
     1319                           1, MPI_REAL, MPI_SUM, comm1dx, ierr )
    8991320#else
    900        mc_factor = mc_factor_l
     1321       volume_flow = volume_flow_l
     1322       mc_factor   = mc_factor_l
    9011323#endif
    9021324
    903        mc_factor = volume_flow_initial(1) / mc_factor
    904 
    905 !
    906 !--    Add disturbance at the inflow
    907        DO  j = nysg, nyng
    908           DO  k = nzb, nzt+1
    909               u(k,j,-nbgp+1:0) = ( mean_inflow_profiles(k,1) +                 &
    910                                    inflow_dist(k,j,1,1)      ) * mc_factor
    911               v(k,j,-nbgp:-1)  = ( mean_inflow_profiles(k,2) +                 &
    912                                    inflow_dist(k,j,2,1)      ) * mc_factor
    913               w(k,j,-nbgp:-1)  =   inflow_dist(k,j,3,1)        * mc_factor
     1325       mc_factor = volume_flow / mc_factor
     1326
     1327!
     1328!--    Add disturbances
     1329       IF ( myidy == id_stg_south  )  THEN
     1330
     1331          DO  i = nxlg, nxrg
     1332             DO  k = nzb, nzt+1
     1333                u(k,-nbgp:-1,i) = ( u(k,-nbgp:-1,i) + dist_xz(k,i,1) )         &
     1334                                     * mc_factor
     1335                v(k,-nbgp:0,i)  = ( v(k,-nbgp:0,i)  + dist_xz(k,i,2)  )        &
     1336                                     * mc_factor
     1337                w(k,-nbgp:-1,i) = ( w(k,-nbgp:-1,i) + dist_xz(k,i,3)  )        &
     1338                                     * mc_factor
     1339             ENDDO
    9141340          ENDDO
    915        ENDDO
    916 
     1341       ENDIF
     1342       IF ( myidy == id_stg_north  )  THEN
     1343
     1344          DO  i = nxlg, nxrg
     1345             DO  k = nzb, nzt+1
     1346                u(k,nyn+1:nyn+nbgp,i) = ( u(k,nyn+1:nyn+nbgp,i) +              &
     1347                                          dist_xz(k,i,1) ) * mc_factor
     1348                v(k,nyn+1:nyn+nbgp,i) = ( v(k,nyn+1:nyn+nbgp,i) +              &
     1349                                          dist_xz(k,i,2) ) * mc_factor
     1350                w(k,nyn+1:nyn+nbgp,i) = ( w(k,nyn+1:nyn+nbgp,i) +              &
     1351                                          dist_xz(k,i,3) ) * mc_factor
     1352             ENDDO
     1353          ENDDO
     1354       ENDIF
    9171355    ENDIF
    9181356
     
    9201358
    9211359 END SUBROUTINE stg_main
    922 
    9231360
    9241361!------------------------------------------------------------------------------!
     
    9311368!> parts are collected to form the full array.
    9321369!------------------------------------------------------------------------------!
    933  SUBROUTINE stg_generate_seed_yz( n_y, n_z, b_y, b_z, f_n )
     1370 SUBROUTINE stg_generate_seed_yz( n_y, n_z, b_y, b_z, f_n, id )
    9341371
    9351372
     
    9401377    IMPLICIT NONE
    9411378
     1379    INTEGER(iwp) :: id          !< core ids at respective boundaries
    9421380    INTEGER(iwp) :: j           !< loop index in y-direction
    9431381    INTEGER(iwp) :: jj          !< loop index in y-direction
     
    9571395    REAL(wp), DIMENSION(-merg:merg,nzb:nzt+1)    :: b_y     !< filter func in y-dir
    9581396    REAL(wp), DIMENSION(-merg:merg,nzb:nzt+1)    :: b_z     !< filter func in z-dir
    959     REAL(wp), DIMENSION(nzb_x:nzt_x+1,nysg:nyng) :: f_n_l   !<  local velocity seed
     1397    REAL(wp), DIMENSION(nzb_x_stg:nzt_x_stg+1,nysg:nyng) :: f_n_l   !<  local velocity seed
    9601398    REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng)     :: f_n     !<  velocity seed
    9611399    REAL(wp), DIMENSION(:,:), ALLOCATABLE        :: rand_it !<  random number
     
    10181456
    10191457    DO  j = nysg, nyng
    1020        DO  k = nzb_x, nzt_x+1
     1458       DO  k = nzb_x_stg, nzt_x_stg+1
    10211459          DO  jj = -n_y2(k), n_y2(k)
    10221460             DO  kk = -n_z2(k), n_z2(k)
     
    10321470!
    10331471!-- Gather velocity seeds of full subdomain
    1034     send_count = nzt_x - nzb_x + 1
    1035     IF ( nzt_x == nzt )  send_count = send_count + 1
     1472    send_count = nzt_x_stg - nzb_x_stg + 1
     1473    IF ( nzt_x_stg == nzt )  send_count = send_count + 1
    10361474
    10371475#if defined( __parallel )
    1038     CALL MPI_GATHERV( f_n_l(nzb_x,nysg), send_count, stg_type_yz_small,        &
    1039                       f_n(nzb+1,nysg), recv_count, displs, stg_type_yz,        &
    1040                       id_inflow, comm1dx, ierr )
     1476    CALL MPI_GATHERV( f_n_l(nzb_x_stg,nysg), send_count, stg_type_yz_small,        &
     1477                      f_n(nzb+1,nysg), recv_count_yz, displs_yz, stg_type_yz,        &
     1478                      id, comm1dx, ierr )
    10411479#else
    1042     f_n(nzb+1:nzt+1,nysg:nyng) = f_n_l(nzb_x:nzt_x+1,nysg:nyng)
     1480    f_n(nzb+1:nzt+1,nysg:nyng) = f_n_l(nzb_x_stg:nzt_x_stg+1,nysg:nyng)
    10431481#endif
    10441482
     
    10461484 END SUBROUTINE stg_generate_seed_yz
    10471485
     1486
     1487
     1488
     1489!------------------------------------------------------------------------------!
     1490! Description:
     1491! ------------
     1492!> Generate a set of random number rand_it wich is equal on each PE
     1493!> and calculate the velocity seed f_n.
     1494!> f_n is splitted in vertical direction by the number of PEs in y-direction and
     1495!> and each PE calculates a vertical subsection of f_n. At the the end, all
     1496!> parts are collected to form the full array.
     1497!------------------------------------------------------------------------------!
     1498 SUBROUTINE stg_generate_seed_xz( n_x, n_z, b_x, b_z, f_n, id )
     1499
     1500
     1501    USE indices,                                                               &
     1502        ONLY: nx
     1503
     1504
     1505    IMPLICIT NONE
     1506
     1507    INTEGER(iwp) :: id          !< core ids at respective boundaries
     1508    INTEGER(iwp) :: i           !< loop index in x-direction
     1509    INTEGER(iwp) :: ii          !< loop index in x-direction
     1510    INTEGER(iwp) :: k           !< loop index in z-direction
     1511    INTEGER(iwp) :: kk          !< loop index in z-direction
     1512    INTEGER(iwp) :: send_count  !< send count for MPI_GATHERV
     1513
     1514    INTEGER(iwp), DIMENSION(nzb:nzt+1) :: n_x    !< length scale in x-direction
     1515    INTEGER(iwp), DIMENSION(nzb:nzt+1) :: n_z    !< length scale in z-direction
     1516    INTEGER(iwp), DIMENSION(nzb:nzt+1) :: n_x2   !< n_y*2
     1517    INTEGER(iwp), DIMENSION(nzb:nzt+1) :: n_z2   !< n_z*2
     1518
     1519    REAL(wp) :: nxz_inv         !< inverse of number of grid points in xz-slice
     1520    REAL(wp) :: rand_av         !< average of random number
     1521    REAL(wp) :: rand_sigma_inv  !< inverse of stdev of random number
     1522
     1523    REAL(wp), DIMENSION(-merg:merg,nzb:nzt+1)    :: b_x     !< filter func in y-dir
     1524    REAL(wp), DIMENSION(-merg:merg,nzb:nzt+1)    :: b_z     !< filter func in z-dir
     1525    REAL(wp), DIMENSION(nzb_y_stg:nzt_y_stg+1,nxlg:nxrg) :: f_n_l   !<  local velocity seed
     1526    REAL(wp), DIMENSION(nzb:nzt+1,nxlg:nxrg)     :: f_n     !<  velocity seed
     1527    REAL(wp), DIMENSION(:,:), ALLOCATABLE        :: rand_it !<  random number
     1528
     1529
     1530!
     1531!-- Generate random numbers using a seed generated in stg_init.
     1532!-- The set of random numbers are modified to have an average of 0 and
     1533!-- unit variance.
     1534    ALLOCATE( rand_it(nzb-mergp:nzt+1+mergp,-mergp:nx+mergp) )
     1535
     1536    rand_av        = 0.0_wp
     1537    rand_sigma_inv = 0.0_wp
     1538    nxz_inv        = 1.0_wp / REAL( ( nzt+1 - nzb+1 ) * ( nx+1 ), KIND=wp )
     1539
     1540    DO  i = 0, nx
     1541       DO  k = nzb, nzt+1
     1542          CALL RANDOM_NUMBER( rand_it(k,i) )
     1543          rand_av = rand_av + rand_it(k,i)
     1544       ENDDO
     1545    ENDDO
     1546
     1547    rand_av = rand_av * nxz_inv
     1548
     1549    DO  i = 0, nx
     1550       DO  k = nzb, nzt+1
     1551          rand_it(k,i)   = rand_it(k,i) - rand_av
     1552          rand_sigma_inv = rand_sigma_inv + rand_it(k,i) ** 2
     1553       ENDDO
     1554    ENDDO
     1555
     1556    rand_sigma_inv = 1.0_wp / SQRT(rand_sigma_inv * nxz_inv)
     1557
     1558    DO  i = 0, nx
     1559       DO  k = nzb, nzt+1
     1560          rand_it(k,i) = rand_it(k,i) * rand_sigma_inv
     1561       ENDDO
     1562    ENDDO
     1563
     1564!
     1565!-- Periodic fill of random number in space
     1566    DO  i = 0, nx
     1567       DO  k = 1, mergp
     1568          rand_it(nzb-k,i)   = rand_it(nzt+2-k,i)    ! bottom margin
     1569          rand_it(nzt+1+k,i) = rand_it(nzb+k-1,i)    ! top margin
     1570       ENDDO
     1571    ENDDO
     1572    DO  i = 1, mergp
     1573       DO  k = nzb-mergp, nzt+1+mergp
     1574          rand_it(k,-i)   = rand_it(k,nx-i+1)        ! left margin
     1575          rand_it(k,nx+i) = rand_it(k,i-1)           ! right margin
     1576       ENDDO
     1577    ENDDO
     1578
     1579!
     1580!-- Generate velocity seed following Eq.6 of Xie and Castro (2008)
     1581    n_x2 = n_x * 2
     1582    n_z2 = n_z * 2
     1583    f_n_l  = 0.0_wp
     1584
     1585    DO  i = nxlg, nxrg
     1586       DO  k = nzb_y_stg, nzt_y_stg+1
     1587          DO  ii = -n_x2(k), n_x2(k)
     1588             DO  kk = -n_z2(k), n_z2(k)
     1589                f_n_l(k,i) = f_n_l(k,i)                                        &
     1590                           + b_x(ii,k) * b_z(kk,k) * rand_it(k+kk,i+ii)
     1591             ENDDO
     1592          ENDDO
     1593       ENDDO
     1594    ENDDO
     1595
     1596    DEALLOCATE( rand_it )
     1597
     1598!
     1599!-- Gather velocity seeds of full subdomain
     1600    send_count = nzt_y_stg - nzb_y_stg + 1
     1601    IF ( nzt_y_stg == nzt )  send_count = send_count + 1
     1602
     1603
     1604#if defined( __parallel )
     1605    CALL MPI_GATHERV( f_n_l(nzb_y_stg,nxlg), send_count, stg_type_xz_small,        &
     1606                      f_n(nzb+1,nxlg), recv_count_xz, displs_xz, stg_type_xz,  &
     1607                      id, comm1dy, ierr )
     1608#else
     1609    f_n(nzb+1:nzt+1,nxlg:nxrg) = f_n_l(nzb_y_stg:nzt_y_stg+1,nxlg:nxrg)
     1610#endif
     1611
     1612
     1613 END SUBROUTINE stg_generate_seed_xz
     1614
    10481615 END MODULE synthetic_turbulence_generator_mod
Note: See TracChangeset for help on using the changeset viewer.