Changeset 3347
- Timestamp:
- Oct 15, 2018 2:21:08 PM (6 years ago)
- Location:
- palm/trunk/SOURCE
- Files:
-
- 1 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
palm/trunk/SOURCE/Makefile
r3337 r3347 25 25 # ----------------- 26 26 # $Id$ 27 # Add module for offline nesting; 28 # Add surface_mod to synthetic-turbulence generator; 29 # Bugfix, missing dependency for turbulence generator in init_3d_model; 30 # Some formatting ajdustments 31 # 32 # 3343 2018-10-15 10:38:52Z suehring 27 33 # (from branch resler) 28 34 # Add biometeorology … … 566 572 netcdf_data_input_mod.f90 \ 567 573 netcdf_interface_mod.f90 \ 574 nesting_offl_mod.f90 \ 568 575 ocean_mod.f90 \ 569 576 outflow_turbulence.f90 \ … … 1005 1012 modules.o \ 1006 1013 netcdf_interface_mod.o \ 1014 nesting_offl_mod.o \ 1007 1015 ocean_mod.o \ 1008 1016 plant_canopy_model_mod.o \ … … 1036 1044 netcdf_data_input_mod.o \ 1037 1045 netcdf_interface_mod.o \ 1046 nesting_offl_mod.o \ 1038 1047 ocean_mod.o \ 1039 1048 plant_canopy_model_mod.o \ … … 1045 1054 surface_layer_fluxes_mod.o \ 1046 1055 surface_mod.o \ 1056 synthetic_turbulence_generator_mod.o \ 1047 1057 turbulence_closure_mod.o \ 1048 1058 urban_surface_mod.o \ … … 1112 1122 mod_kinds.o \ 1113 1123 modules.o \ 1114 netcdf_data_input_mod.o \1115 1124 surface_mod.o 1116 1125 local_stop.o: \ … … 1288 1297 urban_surface_mod.o \ 1289 1298 uv_exposure_model_mod.o 1299 nesting_offl_mod.o: \ 1300 cpulog_mod.o \ 1301 mod_kinds.o \ 1302 modules.o \ 1303 netcdf_data_input_mod.o \ 1304 surface_mod.o 1290 1305 ocean_mod.o: \ 1291 1306 advec_s_pw.o \ … … 1335 1350 modules.o \ 1336 1351 multi_agent_system_mod.o \ 1352 nesting_offl_mod.o \ 1337 1353 netcdf_interface_mod.o \ 1338 1354 ocean_mod.o \ … … 1577 1593 mod_kinds.o \ 1578 1594 modules.o \ 1579 pmc_interface_mod.o 1595 nesting_offl_mod.o \ 1596 pmc_interface_mod.o \ 1597 surface_mod.o 1580 1598 temperton_fft_mod.o: \ 1581 1599 mod_kinds.o \ … … 1600 1618 modules.o \ 1601 1619 multi_agent_system_mod.o \ 1620 nesting_offl_mod.o \ 1602 1621 ocean_mod.o \ 1603 1622 pmc_interface_mod.o \ -
palm/trunk/SOURCE/boundary_conds.f90
r3294 r3347 25 25 ! ----------------- 26 26 ! $Id$ 27 ! Bugfix in setting boundary conditions in offline nesting 28 ! 29 ! 3341 2018-10-15 10:31:27Z suehring 27 30 ! changes concerning modularization of ocean option 28 31 ! … … 293 296 ! 294 297 !-- Vertical nesting: Vertical velocity not zero at the top of the fine grid 295 IF ( .NOT. child_domain .AND. 298 IF ( .NOT. child_domain .AND. .NOT. nesting_offline .AND. & 296 299 TRIM(coupling_mode) /= 'vnested_fine' ) THEN 297 300 w_p(nzt:nzt+1,:,:) = 0.0_wp !< nzt is not a prognostic level (but cf. pres) … … 729 732 !-- in case of nest boundaries. This must not be done in case of vertical nesting 730 733 !-- mode as in that case the lateral boundaries are actually cyclic. 731 !-- @todo: Is this really needed? Boundary values will be overwritten in732 !-- coupler or by Inifor data.733 734 IF ( nesting_mode /= 'vertical' .OR. nesting_offline ) THEN 734 735 IF ( bc_dirichlet_s ) THEN -
palm/trunk/SOURCE/check_parameters.f90
r3337 r3347 25 25 ! ----------------- 26 26 ! $Id$ 27 ! Remove offline nesting in if clause for pressure top boundary condition 28 ! 29 ! 3343 2018-10-15 10:38:52Z suehring 27 30 ! (from branch resler) 28 31 ! Add biometeorology, … … 1954 1957 ibc_p_t = 0 1955 1958 !-- TO_DO: later set bc_p_t to neumann before, in case of nested domain 1956 ELSEIF ( bc_p_t == 'neumann' .OR. bc_p_t == 'nested' .OR. & 1957 bc_p_t == 'nesting_offline' ) THEN 1959 ELSEIF ( bc_p_t == 'neumann' .OR. bc_p_t == 'nested' ) THEN 1958 1960 ibc_p_t = 1 1959 1961 ELSE -
palm/trunk/SOURCE/header.f90
r3302 r3347 25 25 ! ----------------- 26 26 ! $Id$ 27 ! Header output concerning offline nesting 28 ! 29 ! 3343 2018-10-15 10:38:52Z suehring 27 30 ! call of ocean_header 28 31 ! … … 438 441 USE netcdf_interface, & 439 442 ONLY: netcdf_data_format, netcdf_data_format_string, netcdf_deflate 443 444 USE nesting_offl_mod, & 445 ONLY: nesting_offl_header 440 446 441 447 USE ocean_mod, & … … 903 909 !-- Large scale forcing and nudging 904 910 IF ( large_scale_forcing ) CALL lsf_nudging_header( io ) 911 912 ! 913 !-- Offline nesting 914 IF ( nesting_offline ) CALL nesting_offl_header( io ) 905 915 906 916 ! -
palm/trunk/SOURCE/init_3d_model.f90
r3302 r3347 25 25 ! ----------------- 26 26 ! $Id$ 27 ! - Separate offline nesting from large_scale_nudging_mod 28 ! - Improve the synthetic turbulence generator 29 ! 30 ! 3298 2018-10-02 12:21:11Z kanani 31 ! Minor formatting (kanani) 32 ! Added CALL to the chem_emissions module (Russo) 33 ! 34 ! 3294 2018-10-01 02:37:10Z raasch 27 35 ! allocate and set stokes drift velocity profiles 28 36 ! … … 563 571 ONLY: chem_emis, chem_emis_att, init_3d, & 564 572 netcdf_data_input_init_3d, netcdf_data_input_interpolate 573 574 USE nesting_offl_mod, & 575 ONLY: nesting_offl_init 565 576 566 577 USE ocean_mod, & … … 601 612 602 613 USE synthetic_turbulence_generator_mod, & 603 ONLY: stg_init, use_syn_turb_gen 604 614 ONLY: parametrize_inflow_turbulence, stg_adjust, stg_init, & 615 use_syn_turb_gen 616 605 617 USE surface_layer_fluxes_mod, & 606 618 ONLY: init_surface_layer_fluxes … … 2152 2164 IF ( nudging ) CALL nudge_init 2153 2165 ! 2154 !-- Initialize 1D /3D offline-nesting with COSMO model and read data from2155 !-- external file.2156 IF ( large_scale_forcing .OR. nesting_offline) CALL lsf_init2166 !-- Initialize 1D large-scale forcing and nudging and read data from external 2167 !-- ASCII file 2168 IF ( large_scale_forcing ) CALL lsf_init 2157 2169 ! 2158 2170 !-- Initialize surface forcing corresponding to large-scale forcing. Therein, … … 2163 2175 ENDIF 2164 2176 ENDIF 2177 ! 2178 !-- Initializae 3D offline nesting in COSMO model and read data from 2179 !-- external NetCDF file. 2180 IF ( nesting_offline ) CALL nesting_offl_init 2165 2181 ! 2166 2182 !-- Initialize quantities for special advections schemes … … 2279 2295 CALL location_message( 'finished', .TRUE. ) 2280 2296 ENDIF 2281 2297 ! 2298 !-- In case the synthetic turbulence generator does not have any information 2299 !-- about the inflow turbulence, these information will be parametrized 2300 !-- depending on the initial atmospheric conditions and surface properties. 2301 !-- Please note, within pre-determined time intervals these turbulence 2302 !-- information can be updated if desired. 2303 IF ( use_syn_turb_gen .AND. parametrize_inflow_turbulence ) & 2304 CALL stg_adjust 2282 2305 ! 2283 2306 !-- If required, set chemical emissions -
palm/trunk/SOURCE/init_pegrid.f90
r3241 r3347 25 25 ! ----------------- 26 26 ! $Id$ 27 ! Bugfix in setting number of ghost layers in neutral case 28 ! 29 ! 3341 2018-10-15 10:31:27Z suehring 27 30 ! unused variables removed 28 31 ! … … 723 726 ! 724 727 !-- Determine the number of ghost point layers 725 IF ( ( scalar_advec == 'ws-scheme' .AND. .NOT. neutral ) .OR.&728 IF ( scalar_advec == 'ws-scheme' .OR. & 726 729 momentum_advec == 'ws-scheme' ) THEN 727 730 nbgp = 3 -
palm/trunk/SOURCE/land_surface_model_mod.f90
r3274 r3347 25 25 ! ----------------- 26 26 ! $Id$ 27 ! Assign real value instead of integer 28 ! 29 ! 3341 2018-10-15 10:31:27Z suehring 27 30 ! Modularization of all bulk cloud physics code components 28 31 ! … … 2781 2784 vegetation_type_f%var(j,i) = 1 ! bare soil 2782 2785 soil_type_f%var_2d(j,i) = 1 2783 surface_fraction_f%frac(ind_veg_wall,j,i) = 1 2784 surface_fraction_f%frac(ind_pav_green,j,i) = 0 2785 surface_fraction_f%frac(ind_wat_win,j,i) = 0 2786 surface_fraction_f%frac(ind_veg_wall,j,i) = 1.0_wp 2787 surface_fraction_f%frac(ind_pav_green,j,i) = 0.0_wp 2788 surface_fraction_f%frac(ind_wat_win,j,i) = 0.0_wp 2786 2789 ENDIF 2787 2790 -
palm/trunk/SOURCE/large_scale_forcing_nudging_mod.f90
r3294 r3347 25 25 ! ----------------- 26 26 ! $Id$ 27 ! Offline nesting parts are moved to an independent module nesting_offl_mod 28 ! 29 ! 3341 2018-10-15 10:31:27Z suehring 27 30 ! ocean renamed ocean_mode 28 31 ! … … 87 90 88 91 USE control_parameters, & 89 ONLY: bc_dirichlet_l, bc_dirichlet_n, bc_dirichlet_r, bc_dirichlet_s, & 90 bc_lr, bc_ns, bc_pt_b, bc_q_b, constant_diffusion, & 92 ONLY: bc_lr, bc_ns, bc_pt_b, bc_q_b, constant_diffusion, & 91 93 constant_heatflux, constant_waterflux, & 92 94 data_output_pr, dt_3d, end_time, & … … 94 96 ibc_pt_b, ibc_q_b, & 95 97 large_scale_forcing, large_scale_subsidence, lsf_surf, lsf_vert,& 96 lsf_exception, message_string, ne sting_offline, neutral,&98 lsf_exception, message_string, neutral, & 97 99 nudging, passive_scalar, pt_surface, ocean_mode, q_surface, & 98 100 surface_heatflux, surface_pressure, surface_waterflux, & 99 101 topography, use_subsidence_tendencies 102 103 USE cpulog, & 104 ONLY: cpu_log, log_point 100 105 101 106 USE grid_variables … … 107 112 USE kinds 108 113 109 USE netcdf_data_input_mod, &110 ONLY: nest_offl111 112 114 USE pegrid 113 115 … … 120 122 INTEGER(iwp) :: nlsf = 1000 !< maximum number of profiles in LSF_DATA (large scale forcing) 121 123 INTEGER(iwp) :: ntnudge = 1000 !< maximum number of profiles in NUDGING_DATA (nudging) 122 123 REAL(wp) :: d_area_t124 124 125 125 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: ptnudge !< vertical profile of pot. temperature interpolated to vertical grid (nudging) … … 156 156 lsf_nudging_check_parameters, nudge_init, & 157 157 lsf_nudging_check_data_output_pr, lsf_nudging_header, & 158 lsf_nesting_offline, lsf_nesting_offline_mass_conservation, &159 158 nudge, nudge_ref 160 159 … … 177 176 CONTAINS 178 177 179 180 !------------------------------------------------------------------------------!181 ! Description:182 ! ------------183 !> In this subroutine a constant mass within the model domain is guaranteed.184 !> Larger-scale models may be based on a compressible equation system, which is185 !> not consistent with PALMs incompressible equation system. In order to avoid186 !> a decrease or increase of mass during the simulation, non-divergent flow187 !> through the lateral and top boundaries is compensated by the vertical wind188 !> component at the top boundary.189 !------------------------------------------------------------------------------!190 SUBROUTINE lsf_nesting_offline_mass_conservation191 192 USE control_parameters, &193 ONLY: volume_flow194 195 IMPLICIT NONE196 197 INTEGER(iwp) :: i !< grid index in x-direction198 INTEGER(iwp) :: j !< grid index in y-direction199 INTEGER(iwp) :: k !< grid index in z-direction200 201 REAL(wp) :: w_correct !< vertical velocity increment required to compensate non-divergent flow through the boundaries202 REAL(wp), DIMENSION(1:3) :: volume_flow_l !< local volume flow203 204 volume_flow = 0.0_wp205 volume_flow_l = 0.0_wp206 207 d_area_t = 1.0_wp / ( ( nx + 1 ) * dx * ( ny + 1 ) * dy )208 209 IF ( bc_dirichlet_l ) THEN210 i = nxl211 DO j = nys, nyn212 DO k = nzb+1, nzt213 volume_flow_l(1) = volume_flow_l(1) + u(k,j,i) * dzw(k) * dy &214 * MERGE( 1.0_wp, 0.0_wp, &215 BTEST( wall_flags_0(k,j,i), 1 ) )216 ENDDO217 ENDDO218 ENDIF219 IF ( bc_dirichlet_r ) THEN220 i = nxr+1221 DO j = nys, nyn222 DO k = nzb+1, nzt223 volume_flow_l(1) = volume_flow_l(1) - u(k,j,i) * dzw(k) * dy &224 * MERGE( 1.0_wp, 0.0_wp, &225 BTEST( wall_flags_0(k,j,i), 1 ) )226 ENDDO227 ENDDO228 ENDIF229 IF ( bc_dirichlet_s ) THEN230 j = nys231 DO i = nxl, nxr232 DO k = nzb+1, nzt233 volume_flow_l(2) = volume_flow_l(2) + v(k,j,i) * dzw(k) * dx &234 * MERGE( 1.0_wp, 0.0_wp, &235 BTEST( wall_flags_0(k,j,i), 2 ) )236 ENDDO237 ENDDO238 ENDIF239 IF ( bc_dirichlet_n ) THEN240 j = nyn+1241 DO i = nxl, nxr242 DO k = nzb+1, nzt243 volume_flow_l(2) = volume_flow_l(2) - v(k,j,i) * dzw(k) * dx &244 * MERGE( 1.0_wp, 0.0_wp, &245 BTEST( wall_flags_0(k,j,i), 2 ) )246 ENDDO247 ENDDO248 ENDIF249 !250 !-- Top boundary251 k = nzt252 DO i = nxl, nxr253 DO j = nys, nyn254 volume_flow_l(3) = volume_flow_l(3) - w(k,j,i) * dx * dy255 ENDDO256 ENDDO257 258 #if defined( __parallel )259 IF ( collective_wait ) CALL MPI_BARRIER( comm2d, ierr )260 CALL MPI_ALLREDUCE( volume_flow_l, volume_flow, 3, MPI_REAL, MPI_SUM, &261 comm2d, ierr )262 #else263 volume_flow = volume_flow_l264 #endif265 266 w_correct = SUM( volume_flow ) * d_area_t267 268 DO i = nxl, nxr269 DO j = nys, nyn270 DO k = nzt, nzt + 1271 w(k,j,i) = w(k,j,i) + w_correct272 ENDDO273 ENDDO274 ENDDO275 276 END SUBROUTINE lsf_nesting_offline_mass_conservation277 278 279 !------------------------------------------------------------------------------!280 ! Description:281 ! ------------282 !> Set the lateral and top boundary conditions in case the PALM domain is283 !> nested offline in a mesoscale model.284 !------------------------------------------------------------------------------!285 SUBROUTINE lsf_nesting_offline286 287 USE control_parameters, &288 ONLY: bc_dirichlet_l, bc_dirichlet_n, bc_dirichlet_r, &289 bc_dirichlet_s, humidity, neutral, passive_scalar, rans_mode,&290 rans_tke_e, time_since_reference_point291 292 IMPLICIT NONE293 294 INTEGER(iwp) :: i !< running index x-direction295 INTEGER(iwp) :: j !< running index y-direction296 INTEGER(iwp) :: k !< running index z-direction297 298 REAL(wp) :: ddt_lsf !< inverse value of time resolution of forcing data299 REAL(wp) :: t_ref !< time past since last reference step300 301 !302 !-- Calculate time interval of forcing data303 ddt_lsf = 1.0_wp / ( nest_offl%time(nest_offl%tind_p) - &304 nest_offl%time(nest_offl%tind) )305 !306 !-- Calculate reziproke time past since last reference step. Please note,307 !-- the time coordinate is still not updated, so that the actual time need308 !-- to be incremented by dt_3d. Moreover, note that the simulation time309 !-- passed since simulation start is time_since_reference_point, not310 !-- simulated_time!311 t_ref = time_since_reference_point + dt_3d - &312 nest_offl%time(nest_offl%tind)313 314 IF ( bc_dirichlet_l ) THEN315 316 DO j = nys, nyn317 DO k = nzb+1, nzt318 u(k,j,nxlg:nxl) = nest_offl%u_left(0,k,j) + ddt_lsf * t_ref * &319 ( nest_offl%u_left(1,k,j) - nest_offl%u_left(0,k,j) ) * &320 MERGE( 1.0_wp, 0.0_wp, &321 BTEST( wall_flags_0(k,j,nxlg:nxl), 1 ) )322 ENDDO323 ENDDO324 325 DO j = nys, nyn326 DO k = nzb+1, nzt-1327 w(k,j,nxlg:nxl-1) = nest_offl%w_left(0,k,j) + ddt_lsf * t_ref *&328 ( nest_offl%w_left(1,k,j) - nest_offl%w_left(0,k,j) ) *&329 MERGE( 1.0_wp, 0.0_wp, &330 BTEST( wall_flags_0(k,j,nxlg:nxl-1), 3 ) )331 ENDDO332 ENDDO333 334 DO j = nysv, nyn335 DO k = nzb+1, nzt336 v(k,j,nxlg:nxl-1) = nest_offl%v_left(0,k,j) + ddt_lsf * t_ref *&337 ( nest_offl%v_left(1,k,j) - nest_offl%v_left(0,k,j) ) *&338 MERGE( 1.0_wp, 0.0_wp, &339 BTEST( wall_flags_0(k,j,nxlg:nxl-1), 2 ) )340 ENDDO341 ENDDO342 343 IF ( .NOT. neutral ) THEN344 DO j = nys, nyn345 DO k = nzb+1, nzt346 pt(k,j,nxlg:nxl-1) = nest_offl%pt_left(0,k,j) + ddt_lsf * &347 t_ref * &348 ( nest_offl%pt_left(1,k,j) - nest_offl%pt_left(0,k,j) )349 350 ENDDO351 ENDDO352 ENDIF353 354 IF ( humidity ) THEN355 DO j = nys, nyn356 DO k = nzb+1, nzt357 q(k,j,nxlg:nxl-1) = nest_offl%q_left(0,k,j) + ddt_lsf * &358 t_ref * &359 ( nest_offl%q_left(1,k,j) - nest_offl%q_left(0,k,j) )360 361 ENDDO362 ENDDO363 ENDIF364 365 ENDIF366 367 IF ( bc_dirichlet_r ) THEN368 369 DO j = nys, nyn370 DO k = nzb+1, nzt371 u(k,j,nxr+1:nxrg) = nest_offl%u_right(0,k,j) + ddt_lsf * t_ref *&372 ( nest_offl%u_right(1,k,j) - nest_offl%u_right(0,k,j) ) *&373 MERGE( 1.0_wp, 0.0_wp, &374 BTEST( wall_flags_0(k,j,nxr+1:nxrg), 1 ) )375 376 ENDDO377 ENDDO378 DO j = nys, nyn379 DO k = nzb+1, nzt-1380 w(k,j,nxr+1:nxrg) = nest_offl%w_right(0,k,j) + ddt_lsf * t_ref *&381 ( nest_offl%w_right(1,k,j) - nest_offl%w_right(0,k,j) ) *&382 MERGE( 1.0_wp, 0.0_wp, &383 BTEST( wall_flags_0(k,j,nxr+1:nxrg), 3 ) )384 ENDDO385 ENDDO386 387 DO j = nysv, nyn388 DO k = nzb+1, nzt389 v(k,j,nxr+1:nxrg) = nest_offl%v_right(0,k,j) + ddt_lsf * t_ref *&390 ( nest_offl%v_right(1,k,j) - nest_offl%v_right(0,k,j) ) *&391 MERGE( 1.0_wp, 0.0_wp, &392 BTEST( wall_flags_0(k,j,nxr+1:nxrg), 2 ) )393 ENDDO394 ENDDO395 396 IF ( .NOT. neutral ) THEN397 DO j = nys, nyn398 DO k = nzb+1, nzt399 pt(k,j,nxr+1:nxrg) = nest_offl%pt_right(0,k,j) + ddt_lsf * &400 t_ref * &401 ( nest_offl%pt_right(1,k,j) - nest_offl%pt_right(0,k,j) )402 403 ENDDO404 ENDDO405 ENDIF406 407 IF ( humidity ) THEN408 DO j = nys, nyn409 DO k = nzb+1, nzt410 q(k,j,nxr+1:nxrg) = nest_offl%q_right(0,k,j) + ddt_lsf * &411 t_ref * &412 ( nest_offl%q_right(1,k,j) - nest_offl%q_right(0,k,j) )413 414 ENDDO415 ENDDO416 ENDIF417 418 ENDIF419 420 IF ( bc_dirichlet_s ) THEN421 422 DO i = nxl, nxr423 DO k = nzb+1, nzt424 v(k,nysg:nys,i) = nest_offl%v_south(0,k,i) + ddt_lsf * t_ref *&425 ( nest_offl%v_south(1,k,i) - nest_offl%v_south(0,k,i) ) *&426 MERGE( 1.0_wp, 0.0_wp, &427 BTEST( wall_flags_0(k,nysg:nys,i), 2 ) )428 ENDDO429 ENDDO430 431 DO i = nxl, nxr432 DO k = nzb+1, nzt-1433 w(k,nysg:nys-1,i) = nest_offl%w_south(0,k,i) + ddt_lsf * t_ref *&434 ( nest_offl%w_south(1,k,i) - nest_offl%w_south(0,k,i) ) *&435 MERGE( 1.0_wp, 0.0_wp, &436 BTEST( wall_flags_0(k,nysg:nys-1,i), 3 ) )437 ENDDO438 ENDDO439 440 DO i = nxlu, nxr441 DO k = nzb+1, nzt442 u(k,nysg:nys-1,i) = nest_offl%u_south(0,k,i) + ddt_lsf * t_ref *&443 ( nest_offl%u_south(1,k,i) - nest_offl%u_south(0,k,i) ) *&444 MERGE( 1.0_wp, 0.0_wp, &445 BTEST( wall_flags_0(k,nysg:nys-1,i), 1 ) )446 ENDDO447 ENDDO448 449 IF ( .NOT. neutral ) THEN450 DO i = nxl, nxr451 DO k = nzb+1, nzt452 pt(k,nysg:nys-1,i) = nest_offl%pt_south(0,k,i) + ddt_lsf * &453 t_ref * &454 ( nest_offl%pt_south(1,k,i) - nest_offl%pt_south(0,k,i) )455 456 ENDDO457 ENDDO458 ENDIF459 460 IF ( humidity ) THEN461 DO i = nxl, nxr462 DO k = nzb+1, nzt463 q(k,nysg:nys-1,i) = nest_offl%q_south(0,k,i) + ddt_lsf * &464 t_ref * &465 ( nest_offl%q_south(1,k,i) - nest_offl%q_south(0,k,i) )466 467 ENDDO468 ENDDO469 ENDIF470 471 ENDIF472 473 IF ( bc_dirichlet_n ) THEN474 475 DO i = nxl, nxr476 DO k = nzb+1, nzt477 v(k,nyn+1:nyng,i) = nest_offl%v_north(0,k,i) + ddt_lsf * t_ref *&478 ( nest_offl%v_north(1,k,i) - nest_offl%v_north(0,k,i) ) *&479 MERGE( 1.0_wp, 0.0_wp, &480 BTEST( wall_flags_0(k,nyn+1:nyng,i), 2 ) )481 ENDDO482 ENDDO483 DO i = nxl, nxr484 DO k = nzb+1, nzt-1485 w(k,nyn+1:nyng,i) = nest_offl%w_north(0,k,i) + ddt_lsf * t_ref *&486 ( nest_offl%w_north(1,k,i) - nest_offl%w_north(0,k,i) ) *&487 MERGE( 1.0_wp, 0.0_wp, &488 BTEST( wall_flags_0(k,nyn+1:nyng,i), 3 ) )489 ENDDO490 ENDDO491 492 DO i = nxlu, nxr493 DO k = nzb+1, nzt494 u(k,nyn+1:nyng,i) = nest_offl%u_north(0,k,i) + ddt_lsf * t_ref *&495 ( nest_offl%u_north(1,k,i) - nest_offl%u_north(0,k,i) ) *&496 MERGE( 1.0_wp, 0.0_wp, &497 BTEST( wall_flags_0(k,nyn+1:nyng,i), 1 ) )498 499 ENDDO500 ENDDO501 502 IF ( .NOT. neutral ) THEN503 DO i = nxl, nxr504 DO k = nzb+1, nzt505 pt(k,nyn+1:nyng,i) = nest_offl%pt_north(0,k,i) + ddt_lsf * &506 t_ref * &507 ( nest_offl%pt_north(1,k,i) - nest_offl%pt_north(0,k,i) )508 509 ENDDO510 ENDDO511 ENDIF512 513 IF ( humidity ) THEN514 DO i = nxl, nxr515 DO k = nzb+1, nzt516 q(k,nyn+1:nyng,i) = nest_offl%q_north(0,k,i) + ddt_lsf * &517 t_ref * &518 ( nest_offl%q_north(1,k,i) - nest_offl%q_north(0,k,i) )519 520 ENDDO521 ENDDO522 ENDIF523 524 ENDIF525 !526 !-- Top boundary.527 DO i = nxlu, nxr528 DO j = nys, nyn529 u(nzt+1,j,i) = nest_offl%u_top(0,j,i) + ddt_lsf * t_ref * &530 ( nest_offl%u_top(1,j,i) - nest_offl%u_top(0,j,i) ) * &531 MERGE( 1.0_wp, 0.0_wp, &532 BTEST( wall_flags_0(nzt+1,j,i), 1 ) )533 ENDDO534 ENDDO535 536 DO i = nxl, nxr537 DO j = nysv, nyn538 v(nzt+1,j,i) = nest_offl%v_top(0,j,i) + ddt_lsf * t_ref * &539 ( nest_offl%v_top(1,j,i) - nest_offl%v_top(0,j,i) ) * &540 MERGE( 1.0_wp, 0.0_wp, &541 BTEST( wall_flags_0(nzt+1,j,i), 2 ) )542 ENDDO543 ENDDO544 545 DO i = nxl, nxr546 DO j = nys, nyn547 w(nzt:nzt+1,j,i) = nest_offl%w_top(0,j,i) + ddt_lsf * t_ref * &548 ( nest_offl%w_top(1,j,i) - nest_offl%w_top(0,j,i) ) * &549 MERGE( 1.0_wp, 0.0_wp, &550 BTEST( wall_flags_0(nzt:nzt+1,j,i), 3 ) )551 ENDDO552 ENDDO553 554 555 IF ( .NOT. neutral ) THEN556 DO i = nxl, nxr557 DO j = nys, nyn558 pt(nzt+1,j,i) = nest_offl%pt_top(0,j,i) + ddt_lsf * t_ref * &559 ( nest_offl%pt_top(1,j,i) - nest_offl%pt_top(0,j,i) )560 ENDDO561 ENDDO562 ENDIF563 564 IF ( humidity ) THEN565 DO i = nxl, nxr566 DO j = nys, nyn567 q(nzt+1,j,i) = nest_offl%q_top(0,j,i) + ddt_lsf * t_ref * &568 ( nest_offl%q_top(1,j,i) - nest_offl%q_top(0,j,i) )569 ENDDO570 ENDDO571 ENDIF572 !573 !-- At the edges( left-south, left-north, right-south and right-north) set574 !-- data on ghost points.575 IF ( bc_dirichlet_l .AND. bc_dirichlet_s ) THEN576 DO i = 1, nbgp577 u(:,nys-i,nxlg:nxl) = u(:,nys,nxlg:nxl)578 w(:,nys-i,nxlg:nxl-1) = w(:,nys,nxlg:nxl-1)579 IF ( .NOT. neutral ) pt(:,nys-i,nxlg:nxl-1) = pt(:,nys,nxlg:nxl-1)580 IF ( humidity ) q(:,nys-i,nxlg:nxl-1) = q(:,nys,nxlg:nxl-1)581 ENDDO582 DO i = 1, nbgp+1583 v(:,nysv-i,nxlg:nxl-1) = v(:,nysv,nxlg:nxl-1)584 ENDDO585 ENDIF586 IF ( bc_dirichlet_l .AND. bc_dirichlet_n ) THEN587 DO i = 1, nbgp588 u(:,nyn+i,nxlg:nxl) = u(:,nyn,nxlg:nxl)589 v(:,nyn+i,nxlg:nxl-1) = v(:,nyn,nxlg:nxl-1)590 w(:,nyn+i,nxlg:nxl-1) = w(:,nyn,nxlg:nxl-1)591 IF ( .NOT. neutral ) pt(:,nyn+i,nxlg:nxl-1) = pt(:,nyn,nxlg:nxl-1)592 IF ( humidity ) q(:,nyn+i,nxlg:nxl-1) = q(:,nyn,nxlg:nxl-1)593 ENDDO594 ENDIF595 IF ( bc_dirichlet_r .AND. bc_dirichlet_s ) THEN596 DO i = 1, nbgp597 u(:,nys-i,nxr+1:nxrg) = u(:,nys,nxr+1:nxrg)598 w(:,nys-i,nxr+1:nxrg) = w(:,nys,nxr+1:nxrg)599 IF ( .NOT. neutral ) pt(:,nys-i,nxr+1:nxrg) = pt(:,nys,nxr+1:nxrg)600 IF ( humidity ) q(:,nys-i,nxr+1:nxrg) = q(:,nys,nxr+1:nxrg)601 ENDDO602 DO i = 1, nbgp+1603 v(:,nysv-i,nxr+1:nxrg) = v(:,nysv,nxr+1:nxrg)604 ENDDO605 ENDIF606 IF ( bc_dirichlet_r .AND. bc_dirichlet_n ) THEN607 DO i = 1, nbgp608 u(:,nyn+i,nxr+1:nxrg) = u(:,nyn,nxr+1:nxrg)609 v(:,nyn+i,nxr+1:nxrg) = v(:,nyn,nxr+1:nxrg)610 w(:,nyn+i,nxr+1:nxrg) = w(:,nyn,nxr+1:nxrg)611 IF ( .NOT. neutral ) pt(:,nyn+i,nxr+1:nxrg) = pt(:,nyn,nxr+1:nxrg)612 IF ( humidity ) q(:,nyn+i,nxr+1:nxrg) = q(:,nyn,nxr+1:nxrg)613 ENDDO614 ENDIF615 !616 !-- Moreover, set Neumann boundary condition for subgrid-scale TKE,617 !-- passive scalar, dissipation, and chemical species if required618 IF ( rans_mode .AND. rans_tke_e ) THEN619 IF ( bc_dirichlet_l ) diss(:,:,nxl-1) = diss(:,:,nxl)620 IF ( bc_dirichlet_r ) diss(:,:,nxr+1) = diss(:,:,nxr)621 IF ( bc_dirichlet_s ) diss(:,nys-1,:) = diss(:,nys,:)622 IF ( bc_dirichlet_n ) diss(:,nyn+1,:) = diss(:,nyn,:)623 ENDIF624 IF ( .NOT. constant_diffusion ) THEN625 IF ( bc_dirichlet_l ) e(:,:,nxl-1) = e(:,:,nxl)626 IF ( bc_dirichlet_r ) e(:,:,nxr+1) = e(:,:,nxr)627 IF ( bc_dirichlet_s ) e(:,nys-1,:) = e(:,nys,:)628 IF ( bc_dirichlet_n ) e(:,nyn+1,:) = e(:,nyn,:)629 e(nzt+1,:,:) = e(nzt,:,:)630 ENDIF631 IF ( passive_scalar ) THEN632 IF ( bc_dirichlet_l ) s(:,:,nxl-1) = s(:,:,nxl)633 IF ( bc_dirichlet_r ) s(:,:,nxr+1) = s(:,:,nxr)634 IF ( bc_dirichlet_s ) s(:,nys-1,:) = s(:,nys,:)635 IF ( bc_dirichlet_n ) s(:,nyn+1,:) = s(:,nyn,:)636 ENDIF637 638 639 640 CALL exchange_horiz( u, nbgp )641 CALL exchange_horiz( v, nbgp )642 CALL exchange_horiz( w, nbgp )643 IF ( .NOT. neutral ) CALL exchange_horiz( pt, nbgp )644 IF ( humidity ) CALL exchange_horiz( q, nbgp )645 646 !647 !-- Set surface pressure. Please note, time-dependent surface648 !-- pressure would require changes in anelastic approximation and649 !-- treatment of fluxes.650 !-- For the moment, comment this out!651 ! surface_pressure = nest_offl%surface_pressure(nest_offl%tind) + &652 ! ddt_lsf * t_ref * &653 ! ( nest_offl%surface_pressure(nest_offl%tind_p) &654 ! - nest_offl%surface_pressure(nest_offl%tind) )655 656 END SUBROUTINE lsf_nesting_offline657 178 658 179 !------------------------------------------------------------------------------! … … 935 456 ONLY: bc_lr_cyc, bc_ns_cyc 936 457 937 USE netcdf_data_input_mod, &938 ONLY: netcdf_data_input_lsf939 940 458 IMPLICIT NONE 941 459 … … 967 485 REAL(wp) :: r_dummy !< 968 486 969 IF ( nesting_offline ) THEN 970 ! 971 !-- Allocate arrays for geostrophic wind components. Arrays will 972 !-- incorporate 2 time levels in order to interpolate in between. Please 973 !-- note, forcing using geostrophic wind components is only required in 974 !-- case of cyclic boundary conditions. 975 IF ( bc_lr_cyc .AND. bc_ns_cyc ) THEN 976 ALLOCATE( nest_offl%ug(0:1,nzb:nzt+1) ) 977 ALLOCATE( nest_offl%vg(0:1,nzb:nzt+1) ) 487 ALLOCATE( p_surf(0:nlsf), pt_surf(0:nlsf), q_surf(0:nlsf), & 488 qsws_surf(0:nlsf), shf_surf(0:nlsf), & 489 td_lsa_lpt(nzb:nzt+1,0:nlsf), td_lsa_q(nzb:nzt+1,0:nlsf), & 490 td_sub_lpt(nzb:nzt+1,0:nlsf), td_sub_q(nzb:nzt+1,0:nlsf), & 491 time_vert(0:nlsf), time_surf(0:nlsf), & 492 ug_vert(nzb:nzt+1,0:nlsf), vg_vert(nzb:nzt+1,0:nlsf), & 493 wsubs_vert(nzb:nzt+1,0:nlsf) ) 494 495 p_surf = 0.0_wp; pt_surf = 0.0_wp; q_surf = 0.0_wp; qsws_surf = 0.0_wp 496 shf_surf = 0.0_wp; time_vert = 0.0_wp; td_lsa_lpt = 0.0_wp 497 td_lsa_q = 0.0_wp; td_sub_lpt = 0.0_wp; td_sub_q = 0.0_wp 498 time_surf = 0.0_wp; ug_vert = 0.0_wp; vg_vert = 0.0_wp 499 wsubs_vert = 0.0_wp 500 501 ! 502 !-- Array for storing large scale forcing and nudging tendencies at each 503 !-- timestep for data output 504 ALLOCATE( sums_ls_l(nzb:nzt+1,0:7) ) 505 sums_ls_l = 0.0_wp 506 507 ngp_sums_ls = (nz+2)*6 508 509 OPEN ( finput, FILE='LSF_DATA', STATUS='OLD', & 510 FORM='FORMATTED', IOSTAT=ierrn ) 511 512 IF ( ierrn /= 0 ) THEN 513 message_string = 'file LSF_DATA does not exist' 514 CALL message( 'ls_forcing', 'PA0368', 1, 2, 0, 6, 0 ) 515 ENDIF 516 517 ierrn = 0 518 ! 519 !-- First three lines of LSF_DATA contain header 520 READ ( finput, FMT='(a100)', IOSTAT=ierrn ) chmess 521 READ ( finput, FMT='(a100)', IOSTAT=ierrn ) chmess 522 READ ( finput, FMT='(a100)', IOSTAT=ierrn ) chmess 523 524 IF ( ierrn /= 0 ) THEN 525 message_string = 'errors in file LSF_DATA' 526 CALL message( 'ls_forcing', 'PA0369', 1, 2, 0, 6, 0 ) 527 ENDIF 528 529 ! 530 !-- Surface values are read in 531 nt = 0 532 ierrn = 0 533 534 DO WHILE ( time_surf(nt) < end_time ) 535 nt = nt + 1 536 READ ( finput, *, IOSTAT = ierrn ) time_surf(nt), shf_surf(nt), & 537 qsws_surf(nt), pt_surf(nt), & 538 q_surf(nt), p_surf(nt) 539 540 IF ( ierrn /= 0 ) THEN 541 WRITE ( message_string, * ) 'No time dependent surface ' // & 542 'variables in & LSF_DATA for end of run found' 543 544 CALL message( 'ls_forcing', 'PA0363', 1, 2, 0, 6, 0 ) 978 545 ENDIF 979 ! 980 !-- Allocate arrays for reading boundary values. Arrays will incorporate 2 981 !-- time levels in order to interpolate in between. 982 IF ( bc_dirichlet_l ) THEN 983 ALLOCATE( nest_offl%u_left(0:1,nzb+1:nzt,nys:nyn) ) 984 ALLOCATE( nest_offl%v_left(0:1,nzb+1:nzt,nysv:nyn) ) 985 ALLOCATE( nest_offl%w_left(0:1,nzb+1:nzt-1,nys:nyn) ) 986 IF ( humidity ) ALLOCATE( nest_offl%q_left(0:1,nzb+1:nzt,nys:nyn) ) 987 IF ( .NOT. neutral ) ALLOCATE( nest_offl%pt_left(0:1,nzb+1:nzt,nys:nyn) ) 988 ENDIF 989 IF ( bc_dirichlet_r ) THEN 990 ALLOCATE( nest_offl%u_right(0:1,nzb+1:nzt,nys:nyn) ) 991 ALLOCATE( nest_offl%v_right(0:1,nzb+1:nzt,nysv:nyn) ) 992 ALLOCATE( nest_offl%w_right(0:1,nzb+1:nzt-1,nys:nyn) ) 993 IF ( humidity ) ALLOCATE( nest_offl%q_right(0:1,nzb+1:nzt,nys:nyn) ) 994 IF ( .NOT. neutral ) ALLOCATE( nest_offl%pt_right(0:1,nzb+1:nzt,nys:nyn) ) 995 ENDIF 996 IF ( bc_dirichlet_n ) THEN 997 ALLOCATE( nest_offl%u_north(0:1,nzb+1:nzt,nxlu:nxr) ) 998 ALLOCATE( nest_offl%v_north(0:1,nzb+1:nzt,nxl:nxr) ) 999 ALLOCATE( nest_offl%w_north(0:1,nzb+1:nzt-1,nxl:nxr) ) 1000 IF ( humidity ) ALLOCATE( nest_offl%q_north(0:1,nzb+1:nzt,nxl:nxr) ) 1001 IF ( .NOT. neutral ) ALLOCATE( nest_offl%pt_north(0:1,nzb+1:nzt,nxl:nxr) ) 1002 ENDIF 1003 IF ( bc_dirichlet_s ) THEN 1004 ALLOCATE( nest_offl%u_south(0:1,nzb+1:nzt,nxlu:nxr) ) 1005 ALLOCATE( nest_offl%v_south(0:1,nzb+1:nzt,nxl:nxr) ) 1006 ALLOCATE( nest_offl%w_south(0:1,nzb+1:nzt-1,nxl:nxr) ) 1007 IF ( humidity ) ALLOCATE( nest_offl%q_south(0:1,nzb+1:nzt,nxl:nxr) ) 1008 IF ( .NOT. neutral ) ALLOCATE( nest_offl%pt_south(0:1,nzb+1:nzt,nxl:nxr) ) 1009 ENDIF 1010 1011 ALLOCATE( nest_offl%u_top(0:1,nys:nyn,nxlu:nxr) ) 1012 ALLOCATE( nest_offl%v_top(0:1,nysv:nyn,nxl:nxr) ) 1013 ALLOCATE( nest_offl%w_top(0:1,nys:nyn,nxl:nxr) ) 1014 IF ( humidity ) ALLOCATE( nest_offl%q_top(0:1,nys:nyn,nxl:nxr) ) 1015 IF ( .NOT. neutral ) ALLOCATE( nest_offl%pt_top(0:1,nys:nyn,nxl:nxr) ) 1016 1017 ! 1018 !-- Read COSMO data at lateral and top boundaries 1019 CALL netcdf_data_input_lsf 1020 ! 1021 !-- Write COSMO data at lateral and top boundaries 1022 CALL lsf_nesting_offline 1023 ! 1024 !-- After 3D data is initialized, ensure mass conservation 1025 CALL lsf_nesting_offline_mass_conservation 1026 ! 1027 !-- Initialize surface pressure. Please note, time-dependent surface 1028 !-- pressure would require changes in anelastic approximation and 1029 !-- treatment of fluxes. 1030 !-- For the moment, comment this out! 1031 ! surface_pressure = nest_offl%surface_pressure(0) 1032 1033 ELSE 1034 1035 ALLOCATE( p_surf(0:nlsf), pt_surf(0:nlsf), q_surf(0:nlsf), & 1036 qsws_surf(0:nlsf), shf_surf(0:nlsf), & 1037 td_lsa_lpt(nzb:nzt+1,0:nlsf), td_lsa_q(nzb:nzt+1,0:nlsf), & 1038 td_sub_lpt(nzb:nzt+1,0:nlsf), td_sub_q(nzb:nzt+1,0:nlsf), & 1039 time_vert(0:nlsf), time_surf(0:nlsf), & 1040 ug_vert(nzb:nzt+1,0:nlsf), vg_vert(nzb:nzt+1,0:nlsf), & 1041 wsubs_vert(nzb:nzt+1,0:nlsf) ) 1042 1043 p_surf = 0.0_wp; pt_surf = 0.0_wp; q_surf = 0.0_wp; qsws_surf = 0.0_wp 1044 shf_surf = 0.0_wp; time_vert = 0.0_wp; td_lsa_lpt = 0.0_wp 1045 td_lsa_q = 0.0_wp; td_sub_lpt = 0.0_wp; td_sub_q = 0.0_wp 1046 time_surf = 0.0_wp; ug_vert = 0.0_wp; vg_vert = 0.0_wp 1047 wsubs_vert = 0.0_wp 1048 1049 ! 1050 !-- Array for storing large scale forcing and nudging tendencies at each 1051 !-- timestep for data output 1052 ALLOCATE( sums_ls_l(nzb:nzt+1,0:7) ) 1053 sums_ls_l = 0.0_wp 1054 1055 ngp_sums_ls = (nz+2)*6 1056 1057 OPEN ( finput, FILE='LSF_DATA', STATUS='OLD', & 1058 FORM='FORMATTED', IOSTAT=ierrn ) 1059 1060 IF ( ierrn /= 0 ) THEN 1061 message_string = 'file LSF_DATA does not exist' 1062 CALL message( 'ls_forcing', 'PA0368', 1, 2, 0, 6, 0 ) 1063 ENDIF 1064 1065 ierrn = 0 1066 ! 1067 !-- First three lines of LSF_DATA contain header 1068 READ ( finput, FMT='(a100)', IOSTAT=ierrn ) chmess 1069 READ ( finput, FMT='(a100)', IOSTAT=ierrn ) chmess 1070 READ ( finput, FMT='(a100)', IOSTAT=ierrn ) chmess 1071 546 ENDDO 547 548 IF ( time_surf(1) > end_time ) THEN 549 WRITE ( message_string, * ) 'Time dependent surface variables in ' //& 550 '&LSF_DATA set in after end of ' , & 551 'simulation - lsf_surf is set to FALSE' 552 CALL message( 'ls_forcing', 'PA0371', 0, 0, 0, 6, 0 ) 553 lsf_surf = .FALSE. 554 ENDIF 555 556 ! 557 !-- Go to the end of the list with surface variables 558 DO WHILE ( ierrn == 0 ) 559 READ ( finput, *, IOSTAT = ierrn ) r_dummy 560 ENDDO 561 562 ! 563 !-- Profiles of ug, vg and w_subs are read in (large scale forcing) 564 565 nt = 0 566 DO WHILE ( time_vert(nt) < end_time ) 567 nt = nt + 1 568 hash = "#" 569 ierrn = 1 ! not zero 570 ! 571 !-- Search for the next line consisting of "# time", 572 !-- from there onwards the profiles will be read 573 DO WHILE ( .NOT. ( hash == "#" .AND. ierrn == 0 ) ) 574 READ ( finput, *, IOSTAT=ierrn ) hash, time_vert(nt) 575 IF ( ierrn < 0 ) THEN 576 WRITE( message_string, * ) 'No time dependent vertical profiles',& 577 ' in & LSF_DATA for end of run found' 578 CALL message( 'ls_forcing', 'PA0372', 1, 2, 0, 6, 0 ) 579 ENDIF 580 ENDDO 581 582 IF ( nt == 1 .AND. time_vert(nt) > end_time ) EXIT 583 584 READ ( finput, *, IOSTAT=ierrn ) lowheight, lowug_vert, lowvg_vert, & 585 lowwsubs_vert, low_td_lsa_lpt, & 586 low_td_lsa_q, low_td_sub_lpt, & 587 low_td_sub_q 1072 588 IF ( ierrn /= 0 ) THEN 1073 589 message_string = 'errors in file LSF_DATA' … … 1075 591 ENDIF 1076 592 1077 ! 1078 !-- Surface values are read in 1079 nt = 0 1080 ierrn = 0 1081 1082 DO WHILE ( time_surf(nt) < end_time ) 1083 nt = nt + 1 1084 READ ( finput, *, IOSTAT = ierrn ) time_surf(nt), shf_surf(nt), & 1085 qsws_surf(nt), pt_surf(nt), & 1086 q_surf(nt), p_surf(nt) 1087 1088 IF ( ierrn /= 0 ) THEN 1089 WRITE ( message_string, * ) 'No time dependent surface ' // & 1090 'variables in & LSF_DATA for end of run found' 1091 1092 CALL message( 'ls_forcing', 'PA0363', 1, 2, 0, 6, 0 ) 593 READ ( finput, *, IOSTAT=ierrn ) highheight, highug_vert, & 594 highvg_vert, highwsubs_vert, & 595 high_td_lsa_lpt, high_td_lsa_q, & 596 high_td_sub_lpt, high_td_sub_q 597 598 IF ( ierrn /= 0 ) THEN 599 message_string = 'errors in file LSF_DATA' 600 CALL message( 'ls_forcing', 'PA0369', 1, 2, 0, 6, 0 ) 601 ENDIF 602 603 604 DO k = nzb, nzt+1 605 IF ( highheight < zu(k) ) THEN 606 lowheight = highheight 607 lowug_vert = highug_vert 608 lowvg_vert = highvg_vert 609 lowwsubs_vert = highwsubs_vert 610 low_td_lsa_lpt = high_td_lsa_lpt 611 low_td_lsa_q = high_td_lsa_q 612 low_td_sub_lpt = high_td_sub_lpt 613 low_td_sub_q = high_td_sub_q 614 615 ierrn = 0 616 READ ( finput, *, IOSTAT=ierrn ) highheight, highug_vert, & 617 highvg_vert, highwsubs_vert, & 618 high_td_lsa_lpt, & 619 high_td_lsa_q, & 620 high_td_sub_lpt, high_td_sub_q 621 622 IF ( ierrn /= 0 ) THEN 623 WRITE( message_string, * ) 'zu(',k,') = ', zu(k), 'm ', & 624 'is higher than the maximum height in LSF_DATA ', & 625 'which is ', lowheight, 'm. Interpolation on PALM ', & 626 'grid is not possible.' 627 CALL message( 'ls_forcing', 'PA0395', 1, 2, 0, 6, 0 ) 628 ENDIF 629 1093 630 ENDIF 631 632 ! 633 !-- Interpolation of prescribed profiles in space 634 fac = (highheight-zu(k))/(highheight - lowheight) 635 636 ug_vert(k,nt) = fac * lowug_vert & 637 + ( 1.0_wp - fac ) * highug_vert 638 vg_vert(k,nt) = fac * lowvg_vert & 639 + ( 1.0_wp - fac ) * highvg_vert 640 wsubs_vert(k,nt) = fac * lowwsubs_vert & 641 + ( 1.0_wp - fac ) * highwsubs_vert 642 643 td_lsa_lpt(k,nt) = fac * low_td_lsa_lpt & 644 + ( 1.0_wp - fac ) * high_td_lsa_lpt 645 td_lsa_q(k,nt) = fac * low_td_lsa_q & 646 + ( 1.0_wp - fac ) * high_td_lsa_q 647 td_sub_lpt(k,nt) = fac * low_td_sub_lpt & 648 + ( 1.0_wp - fac ) * high_td_sub_lpt 649 td_sub_q(k,nt) = fac * low_td_sub_q & 650 + ( 1.0_wp - fac ) * high_td_sub_q 651 1094 652 ENDDO 1095 653 1096 IF ( time_surf(1) > end_time ) THEN 1097 WRITE ( message_string, * ) 'Time dependent surface variables in ' // & 1098 '&LSF_DATA set in after end of ' , & 1099 'simulation - lsf_surf is set to FALSE' 1100 CALL message( 'ls_forcing', 'PA0371', 0, 0, 0, 6, 0 ) 1101 lsf_surf = .FALSE. 1102 ENDIF 1103 1104 ! 1105 !-- Go to the end of the list with surface variables 1106 DO WHILE ( ierrn == 0 ) 1107 READ ( finput, *, IOSTAT = ierrn ) r_dummy 1108 ENDDO 1109 1110 ! 1111 !-- Profiles of ug, vg and w_subs are read in (large scale forcing) 1112 1113 nt = 0 1114 DO WHILE ( time_vert(nt) < end_time ) 1115 nt = nt + 1 1116 hash = "#" 1117 ierrn = 1 ! not zero 1118 ! 1119 !-- Search for the next line consisting of "# time", 1120 !-- from there onwards the profiles will be read 1121 DO WHILE ( .NOT. ( hash == "#" .AND. ierrn == 0 ) ) 1122 READ ( finput, *, IOSTAT=ierrn ) hash, time_vert(nt) 1123 IF ( ierrn < 0 ) THEN 1124 WRITE( message_string, * ) 'No time dependent vertical profiles',& 1125 ' in & LSF_DATA for end of run found' 1126 CALL message( 'ls_forcing', 'PA0372', 1, 2, 0, 6, 0 ) 1127 ENDIF 1128 ENDDO 1129 1130 IF ( nt == 1 .AND. time_vert(nt) > end_time ) EXIT 1131 1132 READ ( finput, *, IOSTAT=ierrn ) lowheight, lowug_vert, lowvg_vert,& 1133 lowwsubs_vert, low_td_lsa_lpt, & 1134 low_td_lsa_q, low_td_sub_lpt, & 1135 low_td_sub_q 1136 IF ( ierrn /= 0 ) THEN 1137 message_string = 'errors in file LSF_DATA' 1138 CALL message( 'ls_forcing', 'PA0369', 1, 2, 0, 6, 0 ) 1139 ENDIF 1140 1141 READ ( finput, *, IOSTAT=ierrn ) highheight, highug_vert, & 1142 highvg_vert, highwsubs_vert, & 1143 high_td_lsa_lpt, high_td_lsa_q, & 1144 high_td_sub_lpt, high_td_sub_q 1145 1146 IF ( ierrn /= 0 ) THEN 1147 message_string = 'errors in file LSF_DATA' 1148 CALL message( 'ls_forcing', 'PA0369', 1, 2, 0, 6, 0 ) 1149 ENDIF 1150 1151 1152 DO k = nzb, nzt+1 1153 IF ( highheight < zu(k) ) THEN 1154 lowheight = highheight 1155 lowug_vert = highug_vert 1156 lowvg_vert = highvg_vert 1157 lowwsubs_vert = highwsubs_vert 1158 low_td_lsa_lpt = high_td_lsa_lpt 1159 low_td_lsa_q = high_td_lsa_q 1160 low_td_sub_lpt = high_td_sub_lpt 1161 low_td_sub_q = high_td_sub_q 1162 1163 ierrn = 0 1164 READ ( finput, *, IOSTAT=ierrn ) highheight, highug_vert, & 1165 highvg_vert, highwsubs_vert,& 1166 high_td_lsa_lpt, & 1167 high_td_lsa_q, & 1168 high_td_sub_lpt, high_td_sub_q 1169 1170 IF ( ierrn /= 0 ) THEN 1171 WRITE( message_string, * ) 'zu(',k,') = ', zu(k), 'm ', & 1172 'is higher than the maximum height in LSF_DATA ', & 1173 'which is ', lowheight, 'm. Interpolation on PALM ',& 1174 'grid is not possible.' 1175 CALL message( 'ls_forcing', 'PA0395', 1, 2, 0, 6, 0 ) 1176 ENDIF 1177 1178 ENDIF 1179 1180 ! 1181 !-- Interpolation of prescribed profiles in space 1182 fac = (highheight-zu(k))/(highheight - lowheight) 1183 1184 ug_vert(k,nt) = fac * lowug_vert & 1185 + ( 1.0_wp - fac ) * highug_vert 1186 vg_vert(k,nt) = fac * lowvg_vert & 1187 + ( 1.0_wp - fac ) * highvg_vert 1188 wsubs_vert(k,nt) = fac * lowwsubs_vert & 1189 + ( 1.0_wp - fac ) * highwsubs_vert 1190 1191 td_lsa_lpt(k,nt) = fac * low_td_lsa_lpt & 1192 + ( 1.0_wp - fac ) * high_td_lsa_lpt 1193 td_lsa_q(k,nt) = fac * low_td_lsa_q & 1194 + ( 1.0_wp - fac ) * high_td_lsa_q 1195 td_sub_lpt(k,nt) = fac * low_td_sub_lpt & 1196 + ( 1.0_wp - fac ) * high_td_sub_lpt 1197 td_sub_q(k,nt) = fac * low_td_sub_q & 1198 + ( 1.0_wp - fac ) * high_td_sub_q 1199 1200 ENDDO 1201 1202 ENDDO 1203 1204 ! 1205 !-- Large scale vertical velocity has to be zero at the surface 1206 wsubs_vert(nzb,:) = 0.0_wp 654 ENDDO 655 656 ! 657 !-- Large scale vertical velocity has to be zero at the surface 658 wsubs_vert(nzb,:) = 0.0_wp 1207 659 1208 IF ( time_vert(1) > end_time ) THEN 1209 WRITE ( message_string, * ) 'Time dependent large scale profile ',& 1210 'forcing from&LSF_DATA sets in after end of ' ,& 1211 'simulation - lsf_vert is set to FALSE' 1212 CALL message( 'ls_forcing', 'PA0373', 0, 0, 0, 6, 0 ) 1213 lsf_vert = .FALSE. 1214 ENDIF 1215 1216 CLOSE( finput ) 1217 1218 ENDIF 660 IF ( time_vert(1) > end_time ) THEN 661 WRITE ( message_string, * ) 'Time dependent large scale profile ', & 662 'forcing from&LSF_DATA sets in after end of ' , & 663 'simulation - lsf_vert is set to FALSE' 664 CALL message( 'ls_forcing', 'PA0373', 0, 0, 0, 6, 0 ) 665 lsf_vert = .FALSE. 666 ENDIF 667 668 CLOSE( finput ) 1219 669 1220 670 END SUBROUTINE lsf_init -
palm/trunk/SOURCE/netcdf_data_input_mod.f90
r3337 r3347 25 25 ! ----------------- 26 26 ! $Id$ 27 ! Subroutine renamed 28 ! 29 ! 3257 2018-09-17 17:11:46Z suehring 27 30 ! (from branch resler) 28 31 ! Formatting … … 678 681 END INTERFACE netcdf_data_input_init_lsm 679 682 680 INTERFACE netcdf_data_input_ lsf681 MODULE PROCEDURE netcdf_data_input_ lsf682 END INTERFACE netcdf_data_input_ lsf683 INTERFACE netcdf_data_input_offline_nesting 684 MODULE PROCEDURE netcdf_data_input_offline_nesting 685 END INTERFACE netcdf_data_input_offline_nesting 683 686 684 687 INTERFACE netcdf_data_input_surface_data … … 735 738 netcdf_data_input_init, netcdf_data_input_init_lsm, & 736 739 netcdf_data_input_init_3d, & 737 netcdf_data_input_interpolate, netcdf_data_input_ lsf,&740 netcdf_data_input_interpolate, netcdf_data_input_offline_nesting, & 738 741 netcdf_data_input_surface_data, netcdf_data_input_topo 739 742 … … 3078 3081 !> (COSMO) by Inifor. 3079 3082 !------------------------------------------------------------------------------! 3080 SUBROUTINE netcdf_data_input_ lsf3083 SUBROUTINE netcdf_data_input_offline_nesting 3081 3084 3082 3085 USE control_parameters, & … … 3157 3160 ! 3158 3161 !-- Obtain time index for current input starting at 0. 3159 !-- @todo: At the moment time, inINIFOR and simulated time correspond3162 !-- @todo: At the moment INIFOR and simulated time correspond 3160 3163 !-- to each other. If required, adjust to daytime. 3161 3164 nest_offl%tind = MINLOC( ABS( nest_offl%time - & … … 3348 3351 CALL cpu_log( log_point_s(86), 'NetCDF input forcing', 'stop' ) 3349 3352 3350 END SUBROUTINE netcdf_data_input_ lsf3353 END SUBROUTINE netcdf_data_input_offline_nesting 3351 3354 3352 3355 -
palm/trunk/SOURCE/parin.f90
r3313 r3347 25 25 ! ----------------- 26 26 ! $Id$ 27 ! - offline nesting separated from large-scale forcing module 28 ! - top boundary condition for pressure in offline nesting changed 29 ! 30 ! 3343 2018-10-15 10:38:52Z suehring 27 31 ! Introduced reading of date_init to inipar.(Russo) 28 32 ! Add extra profiles for chemistry (basit) … … 477 481 ONLY: mas_parin 478 482 483 USE nesting_offl_mod, & 484 ONLY: nesting_offl_parin 485 479 486 USE netcdf_interface, & 480 487 ONLY: netcdf_data_format, netcdf_deflate, netcdf_precision … … 570 577 loop_optimization, lsf_exception, masking_method, mg_cycles, & 571 578 mg_switch_to_pe0_level, mixing_length_1d, momentum_advec, & 572 most_method, nesting_offline,&579 most_method, & 573 580 netcdf_precision, neutral, ngsrb, & 574 581 nsor, nsor_ini, nudging, nx, ny, nz, ocean_mode, omega, & … … 643 650 loop_optimization, lsf_exception, masking_method, mg_cycles, & 644 651 mg_switch_to_pe0_level, mixing_length_1d, momentum_advec, & 645 most_method, nesting_offline,&652 most_method, & 646 653 netcdf_precision, neutral, ngsrb, & 647 654 nsor, nsor_ini, nudging, nx, ny, nz, ocean_mode, omega, & … … 878 885 CALL gust_parin 879 886 CALL mas_parin 887 CALL nesting_offl_parin 880 888 CALL ocean_parin 881 889 CALL pcm_parin … … 979 987 ! bc_s_t = 'nesting_offline' ! scalar boundary condition is not clear 980 988 ! bc_cs_t = 'nesting_offline' ! same for chemical species 981 bc_p_t = 'neumann' 989 ! 990 !-- For the pressure set Dirichlet conditions, in contrast to the 991 !-- self nesting. This gives less oscilations within the 992 !-- free atmosphere since the pressure solver has more degrees of 993 !-- freedom. In constrast to the self nesting, this might be 994 !-- justified since the top boundary is far away from the domain 995 !-- of interest. 996 bc_p_t = 'dirichlet' !'neumann' 982 997 ENDIF 983 998 -
palm/trunk/SOURCE/pres.f90
r3183 r3347 25 25 ! ----------------- 26 26 ! $Id$ 27 ! Bugfixes in offline nesting. 28 ! Add comment. 29 ! 30 ! 3341 2018-10-15 10:31:27Z suehring 27 31 ! Rename variables for boundary flags and nesting 28 32 ! … … 169 173 dt_3d, gathered_size, ibc_p_b, ibc_p_t, & 170 174 intermediate_timestep_count, intermediate_timestep_count_max, & 171 mg_switch_to_pe0_level, psolver, subdomain_size, & 175 mg_switch_to_pe0_level, nesting_offline, & 176 psolver, subdomain_size, & 172 177 topography, volume_flow, volume_flow_area, volume_flow_initial 173 178 … … 386 391 ENDIF 387 392 388 IF ( ibc_p_b == 1 .AND. ibc_p_t == 1 .AND. 393 IF ( ibc_p_b == 1 .AND. ibc_p_t == 1 .AND. .NOT. nesting_offline .AND. & 389 394 .NOT. child_domain_nvn .AND. intermediate_timestep_count /= 0 ) & 390 395 THEN … … 719 724 volume_flow_l(2) = 0.0_wp 720 725 ENDIF 721 726 ! 727 !-- Add pressure gradients to the velocity components. Note, the loops are 728 !-- running over the entire model domain, even though, in case of non-cyclic 729 !-- boundaries u- and v-component are not prognostic at i=0 and j=0, 730 !-- respectiveley. However, in case of Dirichlet boundary conditions for the 731 !-- velocities, zero-gradient conditions for the pressure are set, so that 732 !-- no modification is imposed at the boundaries. 722 733 !$OMP PARALLEL PRIVATE (i,j,k) 723 734 !$OMP DO -
palm/trunk/SOURCE/synthetic_turbulence_generator_mod.f90
r3289 r3347 25 25 ! ----------------- 26 26 ! $Id$ 27 ! - Revise structure of init routine 28 ! - introduce new parameters to skip STG for some timesteps 29 ! - introduce time-dependent parametrization of Reynolds-stress tensor 30 ! - Bugfix in allocation of mean_inflow_profiles 31 ! 32 ! 3341 2018-10-15 10:31:27Z suehring 27 33 ! Introduce module parameter for number of inflow profiles 28 34 ! … … 122 128 ! Authors: 123 129 ! -------- 124 ! @author Tobias Gronemeier, Atsushi Inagaki, Micha Gryschka, Christoph Knigge 130 ! @author Tobias Gronemeier, Matthias Suehring, Atsushi Inagaki, Micha Gryschka, Christoph Knigge 131 ! 125 132 ! 126 133 ! … … 133 140 !> a time scale for each velocity component. The profiles of length and time 134 141 !> scales, mean u, v, w, e and pt, and all components of the Reynolds stress 135 !> tensor are read from file STG_PROFILES. 142 !> tensor can be either read from file STG_PROFILES, or will be parametrized 143 !> within the boundary layer. 136 144 !> 137 145 !> @todo test restart … … 149 157 150 158 USE arrays_3d, & 151 ONLY: mean_inflow_profiles, u, v,w159 ONLY: mean_inflow_profiles, q, pt, u, v, w, zu, zw 152 160 153 161 USE basic_constants_and_equations_mod, & 154 ONLY: pi162 ONLY: g, kappa, pi 155 163 156 164 USE control_parameters, & … … 159 167 160 168 USE cpulog, & 161 ONLY: cpu_log, log_point , log_point_s169 ONLY: cpu_log, log_point 162 170 163 171 USE indices, & … … 170 178 #endif 171 179 180 USE nesting_offl_mod, & 181 ONLY: zi_ribulk 182 172 183 USE pegrid, & 173 184 ONLY: comm1dx, comm1dy, comm2d, ierr, myidx, myidy, pdims … … 184 195 185 196 186 LOGICAL :: velocity_seed_initialized = .FALSE. !< true after first call of stg_main 187 LOGICAL :: use_syn_turb_gen = .FALSE. !< switch to use synthetic turbulence generator 197 LOGICAL :: velocity_seed_initialized = .FALSE. !< true after first call of stg_main 198 LOGICAL :: parametrize_inflow_turbulence = .FALSE. !< flag indicating that inflow turbulence is either read from file (.FALSE.) or if it parametrized 199 LOGICAL :: use_syn_turb_gen = .FALSE. !< switch to use synthetic turbulence generator 188 200 189 201 INTEGER(iwp) :: id_stg_left !< left lateral boundary core id in case of turbulence generator … … 202 214 INTEGER(iwp) :: nzt_y_stg !< upper bound of z coordinate (required for transposing z on PEs along y) 203 215 204 REAL(wp) :: mc_factor !< mass flux correction factor 205 206 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: displs_xz !< displacement for MPI_GATHERV 207 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: recv_count_xz !< receive count for MPI_GATHERV 208 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: displs_yz !< displacement for MPI_GATHERV 209 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: recv_count_yz !< receive count for MPI_GATHERV 210 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nux !< length scale of u in x direction (in gp) 211 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nuy !< length scale of u in y direction (in gp) 212 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nuz !< length scale of u in z direction (in gp) 213 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nvx !< length scale of v in x direction (in gp) 214 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nvy !< length scale of v in y direction (in gp) 215 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nvz !< length scale of v in z direction (in gp) 216 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nwx !< length scale of w in x direction (in gp) 217 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nwy !< length scale of w in y direction (in gp) 218 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nwz !< length scale of w in z direction (in gp) 219 220 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: seed !< seed of random number for rn-generator 221 222 REAL(wp), DIMENSION(:), ALLOCATABLE :: a11 !< coefficient for Lund rotation 223 REAL(wp), DIMENSION(:), ALLOCATABLE :: a21 !< coefficient for Lund rotation 224 REAL(wp), DIMENSION(:), ALLOCATABLE :: a22 !< coefficient for Lund rotation 225 REAL(wp), DIMENSION(:), ALLOCATABLE :: a31 !< coefficient for Lund rotation 226 REAL(wp), DIMENSION(:), ALLOCATABLE :: a32 !< coefficient for Lund rotation 227 REAL(wp), DIMENSION(:), ALLOCATABLE :: a33 !< coefficient for Lund rotation 228 REAL(wp), DIMENSION(:), ALLOCATABLE :: tu !< Lagrangian time scale of u 229 REAL(wp), DIMENSION(:), ALLOCATABLE :: tv !< Lagrangian time scale of v 230 REAL(wp), DIMENSION(:), ALLOCATABLE :: tw !< Lagrangian time scale of w 231 232 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bux !< filter function for u in x direction 233 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: buy !< filter function for u in y direction 234 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: buz !< filter function for u in z direction 235 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bvx !< filter function for v in x direction 236 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bvy !< filter function for v in y direction 237 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bvz !< filter function for v in z direction 238 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bwx !< filter function for w in y direction 239 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bwy !< filter function for w in y direction 240 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bwz !< filter function for w in z direction 241 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fu_xz !< velocity seed for u at xz plane 242 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fuo_xz !< velocity seed for u at xz plane with new random number 243 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fu_yz !< velocity seed for u at yz plane 244 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fuo_yz !< velocity seed for u at yz plane with new random number 245 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fv_xz !< velocity seed for v at xz plane 246 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fvo_xz !< velocity seed for v at xz plane with new random number 247 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fv_yz !< velocity seed for v at yz plane 248 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fvo_yz !< velocity seed for v at yz plane with new random number 249 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fw_xz !< velocity seed for w at xz plane 250 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fwo_xz !< velocity seed for w at xz plane with new random number 251 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fw_yz !< velocity seed for w at yz plane 252 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fwo_yz !< velocity seed for w at yz plane with new random number 253 216 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: displs_xz !< displacement for MPI_GATHERV 217 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: recv_count_xz !< receive count for MPI_GATHERV 218 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: displs_yz !< displacement for MPI_GATHERV 219 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: recv_count_yz !< receive count for MPI_GATHERV 220 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nux !< length scale of u in x direction (in gp) 221 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nuy !< length scale of u in y direction (in gp) 222 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nuz !< length scale of u in z direction (in gp) 223 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nvx !< length scale of v in x direction (in gp) 224 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nvy !< length scale of v in y direction (in gp) 225 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nvz !< length scale of v in z direction (in gp) 226 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nwx !< length scale of w in x direction (in gp) 227 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nwy !< length scale of w in y direction (in gp) 228 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: nwz !< length scale of w in z direction (in gp) 229 INTEGER(iwp), DIMENSION(:), ALLOCATABLE :: seed !< seed of random number for rn-generator 230 231 REAL(wp) :: cosmo_ref = 10.0_wp !< height of first vertical grid level in mesoscale model, used for calculation of scaling parameters 232 REAL(wp) :: dt_stg_adjust = 300.0_wp !< time interval for adjusting turbulence statistics 233 REAL(wp) :: dt_stg_call = 5.0_wp !< time interval for calling synthetic turbulence generator 234 REAL(wp) :: mc_factor !< mass flux correction factor 235 REAL(wp) :: scale_l !< scaling parameter used for turbulence parametrization - Obukhov length 236 REAL(wp) :: scale_us !< scaling parameter used for turbulence parametrization - friction velocity 237 REAL(wp) :: scale_wm !< scaling parameter used for turbulence parametrization - momentum scale 238 REAL(wp) :: time_stg_adjust = 0.0_wp !< time counter for adjusting turbulence information 239 REAL(wp) :: time_stg_call = 0.0_wp !< time counter for calling generator 240 241 242 REAL(wp),DIMENSION(:), ALLOCATABLE :: r11 !< Reynolds parameter 243 REAL(wp),DIMENSION(:), ALLOCATABLE :: r21 !< Reynolds parameter 244 REAL(wp),DIMENSION(:), ALLOCATABLE :: r22 !< Reynolds parameter 245 REAL(wp),DIMENSION(:), ALLOCATABLE :: r31 !< Reynolds parameter 246 REAL(wp),DIMENSION(:), ALLOCATABLE :: r32 !< Reynolds parameter 247 REAL(wp),DIMENSION(:), ALLOCATABLE :: r33 !< Reynolds parameter 248 249 REAL(wp), DIMENSION(:), ALLOCATABLE :: a11 !< coefficient for Lund rotation 250 REAL(wp), DIMENSION(:), ALLOCATABLE :: a21 !< coefficient for Lund rotation 251 REAL(wp), DIMENSION(:), ALLOCATABLE :: a22 !< coefficient for Lund rotation 252 REAL(wp), DIMENSION(:), ALLOCATABLE :: a31 !< coefficient for Lund rotation 253 REAL(wp), DIMENSION(:), ALLOCATABLE :: a32 !< coefficient for Lund rotation 254 REAL(wp), DIMENSION(:), ALLOCATABLE :: a33 !< coefficient for Lund rotation 255 REAL(wp), DIMENSION(:), ALLOCATABLE :: tu !< Lagrangian time scale of u 256 REAL(wp), DIMENSION(:), ALLOCATABLE :: tv !< Lagrangian time scale of v 257 REAL(wp), DIMENSION(:), ALLOCATABLE :: tw !< Lagrangian time scale of w 258 259 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bux !< filter function for u in x direction 260 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: buy !< filter function for u in y direction 261 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: buz !< filter function for u in z direction 262 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bvx !< filter function for v in x direction 263 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bvy !< filter function for v in y direction 264 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bvz !< filter function for v in z direction 265 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bwx !< filter function for w in y direction 266 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bwy !< filter function for w in y direction 267 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: bwz !< filter function for w in z direction 268 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fu_xz !< velocity seed for u at xz plane 269 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fuo_xz !< velocity seed for u at xz plane with new random number 270 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fu_yz !< velocity seed for u at yz plane 271 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fuo_yz !< velocity seed for u at yz plane with new random number 272 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fv_xz !< velocity seed for v at xz plane 273 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fvo_xz !< velocity seed for v at xz plane with new random number 274 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fv_yz !< velocity seed for v at yz plane 275 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fvo_yz !< velocity seed for v at yz plane with new random number 276 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fw_xz !< velocity seed for w at xz plane 277 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fwo_xz !< velocity seed for w at xz plane with new random number 278 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fw_yz !< velocity seed for w at yz plane 279 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fwo_yz !< velocity seed for w at yz plane with new random number 280 281 REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: dist_xz !< imposed disturbances at north/south boundary 282 REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: dist_yz !< imposed disturbances at north/south boundary 254 283 255 284 ! 256 285 !-- PALM interfaces: 286 !-- Adjust time and lenght scales, Reynolds stress, and filter functions 287 INTERFACE stg_adjust 288 MODULE PROCEDURE stg_adjust 289 END INTERFACE stg_adjust 290 ! 257 291 !-- Input parameter checks to be done in check_parameters 258 292 INTERFACE stg_check_parameters … … 319 353 ! 320 354 !-- Public interfaces 321 PUBLIC stg_ check_parameters, stg_header, stg_init, stg_main, stg_parin,&322 stg_ wrd_global, stg_rrd_global355 PUBLIC stg_adjust, stg_check_parameters, stg_header, stg_init, stg_main, & 356 stg_parin, stg_rrd_global, stg_wrd_global 323 357 324 358 ! 325 359 !-- Public variables 326 PUBLIC id_stg_left, id_stg_north, id_stg_right, id_stg_south, & 327 use_syn_turb_gen 360 PUBLIC dt_stg_call, dt_stg_adjust, id_stg_left, id_stg_north, & 361 id_stg_right, id_stg_south, parametrize_inflow_turbulence, & 362 time_stg_adjust, time_stg_call, use_syn_turb_gen 328 363 329 364 … … 376 411 message_string = 'Using synthetic turbulence generator ' // & 377 412 'requires %initializing_actions = ' // & 378 '"set_constant_profiles" or "read_restart_data"' 413 '"set_constant_profiles" or "read_restart_data"' //& 414 ', if not offline nesting is applied.' 379 415 CALL message( 'stg_check_parameters', 'PA0015', 1, 2, 0, 6, 0 ) 380 416 ENDIF … … 382 418 IF ( bc_lr /= 'dirichlet/radiation' ) THEN 383 419 message_string = 'Using synthetic turbulence generator ' // & 384 'requires &bc_lr = "dirichlet/radiation"' 420 'requires &bc_lr = "dirichlet/radiation", ' // & 421 'if not offline nesting is applied.' 385 422 CALL message( 'stg_check_parameters', 'PA0035', 1, 2, 0, 6, 0 ) 386 423 ENDIF 387 424 IF ( bc_ns /= 'cyclic' ) THEN 388 425 message_string = 'Using synthetic turbulence generator ' // & 389 'requires &bc_ns = "cyclic"' 426 'requires &bc_ns = "cyclic", ' // & 427 'if not offline nesting is applied.' 390 428 CALL message( 'stg_check_parameters', 'PA0037', 1, 2, 0, 6, 0 ) 391 429 ENDIF … … 425 463 WRITE( io, 3 ) 426 464 ENDIF 465 466 IF ( parametrize_inflow_turbulence ) THEN 467 WRITE( io, 4 ) dt_stg_adjust 468 ELSE 469 WRITE( io, 5 ) 470 ENDIF 427 471 428 472 1 FORMAT (//' Synthetic turbulence generator information:'/ & 429 473 ' ------------------------------------------'/) 430 2 FORMAT (' synthetic turbulence generator switched on') 431 3 FORMAT (' synthetic turbulence generator switched off') 474 2 FORMAT (' synthetic turbulence generator is switched on') 475 3 FORMAT (' synthetic turbulence generator is switched off') 476 4 FORMAT (' imposed turbulence statistics are parametrized and ' \\ & 477 'ajdusted to boundary-layer development each ', F8.2, ' s' ) 478 5 FORMAT (' imposed turbulence is read from file' ) 432 479 433 480 END SUBROUTINE stg_header … … 443 490 444 491 USE arrays_3d, & 445 ONLY: dzw, ddzw, u_init, v_init, zu , zw492 ONLY: dzw, ddzw, u_init, v_init, zu 446 493 447 494 USE control_parameters, & … … 460 507 IMPLICIT NONE 461 508 462 LOGICAL :: file_stg_exist = .FALSE. !< flag indicati onwhether parameter file for Reynolds stress and length scales exist509 LOGICAL :: file_stg_exist = .FALSE. !< flag indicating whether parameter file for Reynolds stress and length scales exist 463 510 464 511 #if defined( __parallel ) … … 484 531 REAL(wp) :: d21 !< vertical interpolation for a21 485 532 REAL(wp) :: d22 !< vertical interpolation for a22 486 REAL(wp) :: dum_exp !< dummy variable used for exponential vertical decrease of turbulent length scales487 533 REAL(wp) :: luy !< length scale for u in y direction 488 534 REAL(wp) :: luz !< length scale for u in z direction … … 494 540 REAL(wp) :: zz !< height 495 541 496 REAL(wp) :: length_scale_surface !< typical length scale497 REAL(wp) :: r_ii_0 !< correction factor498 REAL(wp) :: time_scale !< typical time scale499 REAL(wp) :: length_scale_z !< typical length scale500 501 REAL(wp),DIMENSION(nzb:nzt+1) :: r11 !< Reynolds parameter502 REAL(wp),DIMENSION(nzb:nzt+1) :: r21 !< Reynolds parameter503 REAL(wp),DIMENSION(nzb:nzt+1) :: r22 !< Reynolds parameter504 REAL(wp),DIMENSION(nzb:nzt+1) :: r31 !< Reynolds parameter505 REAL(wp),DIMENSION(nzb:nzt+1) :: r32 !< Reynolds parameter506 REAL(wp),DIMENSION(nzb:nzt+1) :: r33 !< Reynolds parameter507 508 542 509 543 #if defined( __parallel ) … … 512 546 513 547 CALL cpu_log( log_point(57), 'synthetic_turbulence_gen', 'start' ) 514 515 IF ( .NOT. ALLOCATED( mean_inflow_profiles ) ) &516 ALLOCATE( mean_inflow_profiles(nzb:nzt+1,1:num_mean_inflow_profiles) )517 518 ALLOCATE ( a11(nzb:nzt+1), a21(nzb:nzt+1), a22(nzb:nzt+1), &519 a31(nzb:nzt+1), a32(nzb:nzt+1), a33(nzb:nzt+1), &520 nux(nzb:nzt+1), nuy(nzb:nzt+1), nuz(nzb:nzt+1), &521 nvx(nzb:nzt+1), nvy(nzb:nzt+1), nvz(nzb:nzt+1), &522 nwx(nzb:nzt+1), nwy(nzb:nzt+1), nwz(nzb:nzt+1), &523 tu(nzb:nzt+1), tv(nzb:nzt+1), tw(nzb:nzt+1) )524 548 525 549 #if defined( __parallel ) … … 615 639 ENDDO 616 640 CALL RANDOM_SEED(put=seed) 617 641 ! 642 !-- Allocate required arrays 643 !-- mean_inflow profiles must not be allocated in offline nesting 644 IF ( .NOT. nesting_offline .AND. .NOT. child_domain ) THEN 645 IF ( .NOT. ALLOCATED( mean_inflow_profiles ) ) & 646 ALLOCATE( mean_inflow_profiles(nzb:nzt+1,1:num_mean_inflow_profiles) ) 647 ENDIF 648 649 ALLOCATE ( a11(nzb:nzt+1), a21(nzb:nzt+1), a22(nzb:nzt+1), & 650 a31(nzb:nzt+1), a32(nzb:nzt+1), a33(nzb:nzt+1), & 651 nux(nzb:nzt+1), nuy(nzb:nzt+1), nuz(nzb:nzt+1), & 652 nvx(nzb:nzt+1), nvy(nzb:nzt+1), nvz(nzb:nzt+1), & 653 nwx(nzb:nzt+1), nwy(nzb:nzt+1), nwz(nzb:nzt+1), & 654 r11(nzb:nzt+1), r21(nzb:nzt+1), r22(nzb:nzt+1), & 655 r31(nzb:nzt+1), r32(nzb:nzt+1), r33(nzb:nzt+1), & 656 tu(nzb:nzt+1), tv(nzb:nzt+1), tw(nzb:nzt+1) ) 657 658 ALLOCATE ( dist_xz(nzb:nzt+1,nxlg:nxrg,3) ) 659 ALLOCATE ( dist_yz(nzb:nzt+1,nysg:nyng,3) ) 660 dist_xz = 0.0_wp 661 dist_yz = 0.0_wp 662 ! 618 663 !-- Read inflow profile 619 664 !-- Height levels of profiles in input profile is as follows: … … 669 714 670 715 CLOSE( 90 ) 671 716 ! 717 !-- Calculate coefficient matrix from Reynolds stress tensor 718 !-- (Lund rotation) 719 CALL calc_coeff_matrix 720 ! 721 !-- No information about turbulence and its length scales are available. 722 !-- Instead, parametrize turbulence which is imposed at the boundaries. 723 !-- Set flag which indicates that turbulence is parametrized, which is done 724 !-- later when energy-balance models are already initialized. This is 725 !-- because the STG needs information about surface properties such as 726 !-- roughness to build 'realistic' turbulence profiles. 672 727 ELSE 673 728 ! 674 !-- Set-up default turbulent length scales. From the numerical point of 675 !-- view the imposed perturbations should not be immediately dissipated 676 !-- by the numerics. The numerical dissipation, however, acts on scales 677 !-- up to 8 x the grid spacing. For this reason, set the turbulence 678 !-- length scale to 8 time the grid spacing. Further, above the boundary 679 !-- layer height, set turbulence lenght scales to zero (equivalent to not 680 !-- imposing any perturbations) in order to save computational costs. 681 !-- Typical length (time) scales of 100 m (s) should be a good compromise 682 !-- between all stratrifications. Near-surface variances are fixed to 683 !-- 0.1 m2/s2, vertical fluxes are one order of magnitude smaller. 684 !-- Vertical fluxes 685 length_scale_surface = 100.0_wp 686 r_ii_0 = 0.1_wp 687 time_scale = 100.0_wp 688 DO k = nzb+1, nzt+1 689 dum_exp = MERGE( -zu(k) / ( 0.3* zu(nzt) ), & 690 0.0_wp, & 691 zu(k) > 0.3 * zu(nzt) & 692 ) 693 length_scale_z = 8.0_wp * MIN( dx, dy, dzw(k) ) 694 695 ! IF ( zu(k) > zi_richardson ) 696 697 nux(k) = MAX( INT( length_scale_z * ddx ), 1 ) 698 nuy(k) = MAX( INT( length_scale_z * ddy ), 1 ) 699 nuz(k) = MAX( INT( length_scale_z * ddzw(k) ), 1 ) 700 nvx(k) = MAX( INT( length_scale_z * ddx ), 1 ) 701 nvy(k) = MAX( INT( length_scale_z * ddy ), 1 ) 702 nvz(k) = MAX( INT( length_scale_z * ddzw(k) ), 1 ) 703 nwx(k) = MAX( INT( length_scale_z * ddx ), 1 ) 704 nwy(k) = MAX( INT( length_scale_z * ddy ), 1 ) 705 nwz(k) = MAX( INT( length_scale_z * ddzw(k) ), 1 ) 706 707 r11(k) = r_ii_0 * EXP( dum_exp ) 708 r22(k) = r_ii_0 * EXP( dum_exp ) 709 r33(k) = r_ii_0 * EXP( dum_exp ) 710 711 r21(k) = 0.1_wp * r_ii_0 * EXP( dum_exp ) 712 r31(k) = 0.1_wp * r_ii_0 * EXP( dum_exp ) 713 r32(k) = 0.1_wp * r_ii_0 * EXP( dum_exp ) 714 715 tu(k) = time_scale 716 tv(k) = time_scale 717 tw(k) = time_scale 718 719 ENDDO 720 721 nux(nzb) = nux(nzb+1) 722 nuy(nzb) = nuy(nzb+1) 723 nuz(nzb) = nuz(nzb+1) 724 nvx(nzb) = nvx(nzb+1) 725 nvy(nzb) = nvy(nzb+1) 726 nvz(nzb) = nvz(nzb+1) 727 nwx(nzb) = nwx(nzb+1) 728 nwy(nzb) = nwy(nzb+1) 729 nwz(nzb) = nwz(nzb+1) 730 731 r11(nzb) = r11(nzb+1) 732 r22(nzb) = r22(nzb+1) 733 r33(nzb) = r33(nzb+1) 734 735 r21(nzb) = r11(nzb+1) 736 r31(nzb) = r31(nzb+1) 737 r32(nzb) = r32(nzb+1) 738 739 tu(nzb) = time_scale 740 tv(nzb) = time_scale 741 tw(nzb) = time_scale 742 729 !-- Set flag indicating that turbulence is parametrized 730 parametrize_inflow_turbulence = .TRUE. 731 ! 732 !-- Determine boundary-layer depth, which is used to initialize lenght 733 !-- scales 734 CALL calc_scaling_variables 735 ! 736 !-- Initialize lenght and time scales, which in turn are used 737 !-- to initialize the filter functions. 738 CALL calc_length_and_time_scale 739 743 740 ENDIF 744 741 745 742 ! 746 !-- Assign initial profiles 743 !-- Assign initial profiles. Note, this is only required if turbulent 744 !-- inflow from the left is desired, not in case of any of the 745 !-- nesting (offline or self nesting) approaches. 747 746 IF ( .NOT. nesting_offline .AND. .NOT. child_domain ) THEN 748 747 u_init = mean_inflow_profiles(:,1) … … 751 750 e_init = MAXVAL( mean_inflow_profiles(:,5) ) 752 751 ENDIF 753 ! 754 !-- Calculate coefficient matrix from Reynolds stress tensor (Lund rotation) 755 DO k = nzb, nzt+1 756 IF ( r11(k) > 0.0_wp ) THEN 757 a11(k) = SQRT( r11(k) ) 758 a21(k) = r21(k) / a11(k) 759 ELSE 760 a11(k) = 0.0_wp 761 a21(k) = 0.0_wp 762 ENDIF 763 764 a22(k) = r22(k) - a21(k)**2 765 IF ( a22(k) > 0.0_wp ) THEN 766 a22(k) = SQRT( a22(k) ) 767 ELSE 768 a22(k) = 0.0_wp 769 ENDIF 770 771 ! 772 !-- a31, a32, a33 must be calculated with interpolated a11, a21, a22 (d11, 773 !-- d21, d22) because of different vertical grid 774 IF ( k .le. nzt ) THEN 775 d11 = 0.5_wp * ( r11(k) + r11(k+1) ) 776 IF ( d11 > 0.0_wp ) THEN 777 d11 = SQRT( d11 ) 778 d21 = ( 0.5_wp * ( r21(k) + r21(k+1) ) ) / d11 779 a31(k) = r31(k) / d11 780 ELSE 781 d21 = 0.0_wp 782 a31(k) = 0.0_wp 783 ENDIF 784 785 d22 = 0.5_wp * ( r22(k) + r22(k+1) ) - d21 ** 2 786 IF ( d22 > 0.0_wp ) THEN 787 a32(k) = ( r32(k) - d21 * a31(k) ) / SQRT( d22 ) 788 ELSE 789 a32(k) = 0.0_wp 790 ENDIF 791 792 a33(k) = r33(k) - a31(k) ** 2 - a32(k) ** 2 793 IF ( a33(k) > 0.0_wp ) THEN 794 a33(k) = SQRT( a33(k) ) 795 ELSE 796 a33(k) = 0.0_wp 797 ENDIF 798 ELSE 799 a31(k) = a31(k-1) 800 a32(k) = a32(k-1) 801 a33(k) = a33(k-1) 802 ENDIF 803 804 ENDDO 752 805 753 ! 806 754 !-- Define the size of the filter functions and allocate them. … … 961 909 ENDDO 962 910 963 END SUBROUTINE stg_filter_func911 END SUBROUTINE stg_filter_func 964 912 965 913 … … 977 925 978 926 979 NAMELIST /stg_par/ use_syn_turb_gen927 NAMELIST /stg_par/ dt_stg_adjust, dt_stg_call, use_syn_turb_gen 980 928 981 929 line = ' ' … … 1108 1056 REAL(wp) :: volume_flow_l !< local mass flux through lateral boundary 1109 1057 1110 REAL(wp), DIMENSION(nzb:nzt+1,nxlg:nxrg,5) :: dist_xz !< imposed disturbances at north/south boundary1111 REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,5) :: dist_yz !< imposed disturbances at left/right boundary1112 1113 1114 1058 CALL cpu_log( log_point(57), 'synthetic_turbulence_gen', 'start' ) 1115 1059 1116 1060 ! 1117 1061 !-- Calculate time step which is needed for filter functions 1118 dt_stg = dt_3d * weight_substep(intermediate_timestep_count) 1119 1062 dt_stg = MAX( dt_3d, dt_stg_call ) !* weight_substep(intermediate_timestep_count) 1120 1063 ! 1121 1064 !-- Initial value of fu, fv, fw … … 1145 1088 velocity_seed_initialized = .TRUE. 1146 1089 ENDIF 1090 1147 1091 ! 1148 1092 !-- New set of fu, fv, fw … … 1150 1094 CALL stg_generate_seed_yz( nvy, nvz, bvy, bvz, fvo_yz, id_stg_left ) 1151 1095 CALL stg_generate_seed_yz( nwy, nwz, bwy, bwz, fwo_yz, id_stg_left ) 1152 1096 1153 1097 IF ( nesting_offline .OR. ( child_domain .AND. rans_mode_parent & 1154 1155 ! 1156 !-- 1157 1158 1159 1160 ! 1161 !-- 1162 1163 1164 1165 ! 1166 !-- 1167 1168 1169 1098 .AND. .NOT. rans_mode ) ) THEN 1099 ! 1100 !-- Generate turbulence at right boundary 1101 CALL stg_generate_seed_yz( nuy, nuz, buy, buz, fuo_yz, id_stg_right ) 1102 CALL stg_generate_seed_yz( nvy, nvz, bvy, bvz, fvo_yz, id_stg_right ) 1103 CALL stg_generate_seed_yz( nwy, nwz, bwy, bwz, fwo_yz, id_stg_right ) 1104 ! 1105 !-- Generate turbulence at north boundary 1106 CALL stg_generate_seed_xz( nux, nuz, bux, buz, fuo_xz, id_stg_north ) 1107 CALL stg_generate_seed_xz( nvx, nvz, bvx, bvz, fvo_xz, id_stg_north ) 1108 CALL stg_generate_seed_xz( nwx, nwz, bwx, bwz, fwo_xz, id_stg_north ) 1109 ! 1110 !-- Generate turbulence at south boundary 1111 CALL stg_generate_seed_xz( nux, nuz, bux, buz, fuo_xz, id_stg_south ) 1112 CALL stg_generate_seed_xz( nvx, nvz, bvx, bvz, fvo_xz, id_stg_south ) 1113 CALL stg_generate_seed_xz( nwx, nwz, bwx, bwz, fwo_xz, id_stg_south ) 1170 1114 ENDIF 1115 1171 1116 ! 1172 1117 !-- Turbulence generation at left and or right boundary 1173 1118 IF ( myidx == id_stg_left .OR. myidx == id_stg_right ) THEN 1174 1119 1175 1120 DO j = nysg, nyng 1176 1121 DO k = nzb, nzt + 1 … … 1180 1125 fu_yz(k,j) = fuo_yz(k,j) 1181 1126 ELSE 1182 fu_yz(k,j) = fu_yz(k,j) * EXP( -pi * dt_stg * 0.5_wp / tu(k) ) + 1127 fu_yz(k,j) = fu_yz(k,j) * EXP( -pi * dt_stg * 0.5_wp / tu(k) ) + & 1183 1128 fuo_yz(k,j) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tu(k) ) ) 1184 1129 ENDIF … … 1187 1132 fv_yz(k,j) = fvo_yz(k,j) 1188 1133 ELSE 1189 fv_yz(k,j) = fv_yz(k,j) * EXP( -pi * dt_stg * 0.5_wp / tv(k) ) + 1134 fv_yz(k,j) = fv_yz(k,j) * EXP( -pi * dt_stg * 0.5_wp / tv(k) ) + & 1190 1135 fvo_yz(k,j) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tv(k) ) ) 1191 1136 ENDIF … … 1194 1139 fw_yz(k,j) = fwo_yz(k,j) 1195 1140 ELSE 1196 fw_yz(k,j) = fw_yz(k,j) * EXP( -pi * dt_stg * 0.5_wp / tw(k) ) + 1141 fw_yz(k,j) = fw_yz(k,j) * EXP( -pi * dt_stg * 0.5_wp / tw(k) ) + & 1197 1142 fwo_yz(k,j) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tw(k) ) ) 1198 1143 ENDIF … … 1204 1149 dist_yz(k,j,2) = 0.0_wp 1205 1150 dist_yz(k,j,3) = 0.0_wp 1206 ! dist_yz(k,j,4) = 0.0_wp1207 ! dist_yz(k,j,5) = 0.0_wp1208 1151 ELSE 1209 dist_yz(k,j,1) = a11(k) * fu_yz(k,j)1152 dist_yz(k,j,1) = MIN( a11(k) * fu_yz(k,j), 3.0_wp ) 1210 1153 !experimental test of 1.2 1211 dist_yz(k,j,2) = ( SQRT( a22(k) / MAXVAL(a22) ) & 1212 * 1.2_wp ) & 1213 * ( a21(k) * fu_yz(k,j) & 1214 + a22(k) * fv_yz(k,j) ) 1215 dist_yz(k,j,3) = ( SQRT(a33(k) / MAXVAL(a33) ) & 1216 * 1.3_wp ) & 1217 * ( a31(k) * fu_yz(k,j) & 1218 + a32(k) * fv_yz(k,j) & 1219 + a33(k) * fw_yz(k,j) ) 1220 ! Calculation for pt and e not yet implemented 1221 ! dist_yz(k,j,4) = 0.0_wp 1222 ! dist_yz(k,j,5) = 0.0_wp 1154 dist_yz(k,j,2) = MIN( ( SQRT( a22(k) / MAXVAL(a22) ) & 1155 * 1.2_wp ) & 1156 * ( a21(k) * fu_yz(k,j) & 1157 + a22(k) * fv_yz(k,j) ), 3.0_wp ) 1158 dist_yz(k,j,3) = MIN( ( SQRT(a33(k) / MAXVAL(a33) ) & 1159 * 1.3_wp ) & 1160 * ( a31(k) * fu_yz(k,j) & 1161 + a32(k) * fv_yz(k,j) & 1162 + a33(k) * fw_yz(k,j) ), 3.0_wp ) 1223 1163 ENDIF 1224 1164 … … 1241 1181 1242 1182 #if defined( __parallel ) 1243 CALL MPI_ALLREDUCE( mc_factor_l, mc_factor, &1244 1, MPI_REAL, MPI_SUM,comm1dy, ierr )1183 CALL MPI_ALLREDUCE( mc_factor_l, mc_factor, 1, MPI_REAL, MPI_SUM, & 1184 comm1dy, ierr ) 1245 1185 #else 1246 1186 mc_factor = mc_factor_l … … 1298 1238 !-- Add disturbances 1299 1239 IF ( myidx == id_stg_left ) THEN 1300 1301 1240 DO j = nys, nyn 1302 DO k = nzb , nzt1241 DO k = nzb+1, nzt 1303 1242 u(k,j,0) = ( u(k,j,0) + dist_yz(k,j,1) ) & 1304 1243 * mc_factor * MERGE( 1.0_wp, 0.0_wp, & 1305 1244 BTEST( wall_flags_0(k,j,0), 1 ) ) 1245 u(k,j,-1) = u(k,j,0) 1306 1246 v(k,j,-1) = ( v(k,j,-1) + dist_yz(k,j,2) ) & 1307 1247 * mc_factor * MERGE( 1.0_wp, 0.0_wp, & … … 1314 1254 ENDIF 1315 1255 IF ( myidx == id_stg_right ) THEN 1316 1317 1256 DO j = nys, nyn 1318 DO k = nzb , nzt1257 DO k = nzb+1, nzt 1319 1258 u(k,j,nxr+1) = ( u(k,j,nxr+1) + dist_yz(k,j,1) ) & 1320 1259 * mc_factor * MERGE( 1.0_wp, 0.0_wp, & … … 1335 1274 !-- Turbulence generation at north and south boundary 1336 1275 IF ( myidy == id_stg_north .OR. myidy == id_stg_south ) THEN 1337 1276 1338 1277 DO i = nxlg, nxrg 1339 1278 DO k = nzb, nzt + 1 … … 1351 1290 ELSE 1352 1291 fv_xz(k,i) = fv_xz(k,i) * EXP( -pi * dt_stg * 0.5_wp / tv(k) ) + & 1353 1292 fvo_xz(k,i) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tv(k) ) ) 1354 1293 ENDIF 1355 1294 1356 1295 IF ( tw(k) == 0.0_wp ) THEN 1357 1296 fw_xz(k,i) = fwo_xz(k,i) 1358 1297 ELSE 1359 1298 fw_xz(k,i) = fw_xz(k,i) * EXP( -pi * dt_stg * 0.5_wp / tw(k) ) + & 1360 1299 fwo_xz(k,i) * SQRT( 1.0_wp - EXP( -pi * dt_stg / tw(k) ) ) 1361 1300 ENDIF 1362 1301 ! … … 1369 1308 1370 1309 ELSE 1371 dist_xz(k,i,1) = a11(k) * fu_xz(k,i)1310 dist_xz(k,i,1) = MIN( a11(k) * fu_xz(k,i), 3.0_wp ) 1372 1311 !experimental test of 1.2 1373 dist_xz(k,i,2) = ( SQRT( a22(k) / MAXVAL(a22) )&1374 * 1.2_wp )&1375 * ( a21(k) * fu_xz(k,i)&1376 + a22(k) * fv_xz(k,i))1377 dist_xz(k,i,3) = ( SQRT(a33(k) / MAXVAL(a33) )&1378 * 1.3_wp )&1379 * ( a31(k) * fu_xz(k,i)&1380 + a32(k) * fv_xz(k,i)&1381 + a33(k) * fw_xz(k,i))1312 dist_xz(k,i,2) = MIN( ( SQRT( a22(k) / MAXVAL(a22) ) & 1313 * 1.2_wp ) & 1314 * ( a21(k) * fu_xz(k,i) & 1315 + a22(k) * fv_xz(k,i) ), 3.0_wp ) 1316 dist_xz(k,i,3) = MIN( ( SQRT(a33(k) / MAXVAL(a33) ) & 1317 * 1.3_wp ) & 1318 * ( a31(k) * fu_xz(k,i) & 1319 + a32(k) * fv_xz(k,i) & 1320 + a33(k) * fw_xz(k,i) ), 3.0_wp ) 1382 1321 ENDIF 1383 1322 1384 1323 ENDDO 1385 1324 ENDDO 1325 1386 1326 ! 1387 1327 !-- Mass flux correction following Kim et al. (2013) … … 1425 1365 1426 1366 DO i = nxl, nxr 1427 DO k = nzb , nzt1367 DO k = nzb+1, nzt 1428 1368 u(k,-1,i) = ( u(k,-1,i) + dist_xz(k,i,1) ) & 1429 1369 * mc_factor * MERGE( 1.0_wp, 0.0_wp, & … … 1432 1372 * mc_factor * MERGE( 1.0_wp, 0.0_wp, & 1433 1373 BTEST( wall_flags_0(k,0,i), 2 ) ) 1374 v(k,-1,i) = v(k,0,i) 1434 1375 w(k,-1,i) = ( w(k,-1,i) + dist_xz(k,i,3) ) & 1435 1376 * mc_factor * MERGE( 1.0_wp, 0.0_wp, & … … 1441 1382 1442 1383 DO i = nxl, nxr 1443 DO k = nzb , nzt1444 u(k,nyn+1,i) = ( u(k,nyn+1,i) + dist_xz(k,i,1) ) 1445 * mc_factor * MERGE( 1.0_wp, 0.0_wp, 1384 DO k = nzb+1, nzt 1385 u(k,nyn+1,i) = ( u(k,nyn+1,i) + dist_xz(k,i,1) ) & 1386 * mc_factor * MERGE( 1.0_wp, 0.0_wp, & 1446 1387 BTEST( wall_flags_0(k,nyn+1,i), 1 ) ) 1447 v(k,nyn+1,i) = ( v(k,nyn+1,i) + dist_xz(k,i, 1) )&1448 * mc_factor * MERGE( 1.0_wp, 0.0_wp, 1388 v(k,nyn+1,i) = ( v(k,nyn+1,i) + dist_xz(k,i,2) ) & 1389 * mc_factor * MERGE( 1.0_wp, 0.0_wp, & 1449 1390 BTEST( wall_flags_0(k,nyn+1,i), 2 ) ) 1450 w(k,nyn+1,i) = ( w(k,nyn+1,i) + dist_xz(k,i, 1) )&1451 * mc_factor * MERGE( 1.0_wp, 0.0_wp, 1391 w(k,nyn+1,i) = ( w(k,nyn+1,i) + dist_xz(k,i,3) ) & 1392 * mc_factor * MERGE( 1.0_wp, 0.0_wp, & 1452 1393 BTEST( wall_flags_0(k,nyn+1,i), 3 ) ) 1453 1394 ENDDO … … 1455 1396 ENDIF 1456 1397 ENDIF 1398 ! 1399 !-- Finally, set time counter for calling STG to zero 1400 time_stg_call = 0.0_wp 1457 1401 1458 1402 CALL cpu_log( log_point(57), 'synthetic_turbulence_gen', 'stop' ) … … 1493 1437 REAL(wp) :: rand_sigma_inv !< inverse of stdev of random number 1494 1438 1495 REAL(wp), DIMENSION(-merg:merg,nzb:nzt+1) :: b_y !< filter func in y-dir1496 REAL(wp), DIMENSION(-merg:merg,nzb:nzt+1) :: b_z !< filter func in z-dir1439 REAL(wp), DIMENSION(-merg:merg,nzb:nzt+1) :: b_y !< filter function in y-direction 1440 REAL(wp), DIMENSION(-merg:merg,nzb:nzt+1) :: b_z !< filter function in z-direction 1497 1441 REAL(wp), DIMENSION(nzb_x_stg:nzt_x_stg+1,nysg:nyng) :: f_n_l !< local velocity seed 1498 1442 REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng) :: f_n !< velocity seed … … 1613 1557 INTEGER(iwp), DIMENSION(nzb:nzt+1) :: n_x !< length scale in x-direction 1614 1558 INTEGER(iwp), DIMENSION(nzb:nzt+1) :: n_z !< length scale in z-direction 1615 INTEGER(iwp), DIMENSION(nzb:nzt+1) :: n_x2 !< n_ y*21559 INTEGER(iwp), DIMENSION(nzb:nzt+1) :: n_x2 !< n_x*2 1616 1560 INTEGER(iwp), DIMENSION(nzb:nzt+1) :: n_z2 !< n_z*2 1617 1561 … … 1620 1564 REAL(wp) :: rand_sigma_inv !< inverse of stdev of random number 1621 1565 1622 REAL(wp), DIMENSION(-merg:merg,nzb:nzt+1) :: b_x !< filter func in y-dir1623 REAL(wp), DIMENSION(-merg:merg,nzb:nzt+1) :: b_z !< filter func in z-dir1566 REAL(wp), DIMENSION(-merg:merg,nzb:nzt+1) :: b_x !< filter function in x-direction 1567 REAL(wp), DIMENSION(-merg:merg,nzb:nzt+1) :: b_z !< filter function in z-direction 1624 1568 REAL(wp), DIMENSION(nzb_y_stg:nzt_y_stg+1,nxlg:nxrg) :: f_n_l !< local velocity seed 1625 1569 REAL(wp), DIMENSION(nzb:nzt+1,nxlg:nxrg) :: f_n !< velocity seed … … 1712 1656 END SUBROUTINE stg_generate_seed_xz 1713 1657 1658 !------------------------------------------------------------------------------! 1659 ! Description: 1660 ! ------------ 1661 !> Parametrization of the Reynolds stress tensor, following the parametrization 1662 !> described in Rotach et al. (1996), which is applied in state-of-the-art 1663 !> dispserion modelling. Please note, the parametrization does not distinguish 1664 !> between along-wind and cross-wind turbulence. 1665 !------------------------------------------------------------------------------! 1666 SUBROUTINE parametrize_reynolds_stress 1667 1668 USE arrays_3d, & 1669 ONLY: zu 1670 1671 IMPLICIT NONE 1672 1673 INTEGER(iwp) :: k !< loop index in z-direction 1674 1675 REAL(wp) :: zzi !< ratio of z/zi 1676 1677 ! 1678 !-- 1679 DO k = nzb+1, nzt+1 1680 1681 IF ( zu(k) <= zi_ribulk ) THEN 1682 ! 1683 !-- Determine normalized height coordinate 1684 zzi = zu(k) / zi_ribulk 1685 ! 1686 !-- u'u' and v'v'. Assume isotropy. Note, add a small negative number 1687 !-- to the denominator, else the merge-function can crash if scale_l is 1688 !-- zero. 1689 r11(k) = scale_us**2 * ( & 1690 MERGE( 0.35_wp * ( & 1691 - zi_ribulk / ( kappa * scale_l - 10E-4_wp ) & 1692 )**( 2.0_wp / 3.0_wp ), & 1693 0.0_wp, & 1694 scale_l < 0.0_wp ) & 1695 + 5.0_wp - 4.0_wp * zzi & 1696 ) 1697 1698 r22(k) = r11(k) 1699 ! 1700 !-- w'w' 1701 r33(k) = scale_wm**2 * ( & 1702 1.5_wp * zzi**( 2.0_wp / 3.0_wp ) * EXP( -2.0_wp * zzi ) & 1703 + ( 1.7_wp - zzi ) * ( scale_us / scale_wm )**2 & 1704 ) 1705 ! 1706 !-- u'w' and v'w'. Assume isotropy. 1707 r31(k) = - scale_us**2 * ( & 1708 1.0_wp - EXP( 3.0_wp * ( zzi - 1.0_wp ) ) & 1709 ) 1710 1711 r32(k) = r31(k) 1712 ! 1713 !-- For u'v' no parametrization exist so far - ?. For simplicity assume 1714 !-- a similar profile as for u'w'. 1715 r21(k) = r31(k) 1716 ! 1717 !-- Above the boundary layer, assmume laminar flow conditions. 1718 ELSE 1719 r11(k) = 10E-8_wp 1720 r22(k) = 10E-8_wp 1721 r33(k) = 10E-8_wp 1722 r21(k) = 10E-8_wp 1723 r31(k) = 10E-8_wp 1724 r32(k) = 10E-8_wp 1725 ENDIF 1726 ! write(9,*) zu(k), r11(k), r33(k), r31(k), zi_ribulk, scale_us, scale_wm, scale_l 1727 ENDDO 1728 1729 ! 1730 !-- Set bottom boundary condition 1731 r11(nzb) = r11(nzb+1) 1732 r22(nzb) = r22(nzb+1) 1733 r33(nzb) = r33(nzb+1) 1734 1735 r21(nzb) = r11(nzb+1) 1736 r31(nzb) = r31(nzb+1) 1737 r32(nzb) = r32(nzb+1) 1738 1739 1740 END SUBROUTINE parametrize_reynolds_stress 1741 1742 !------------------------------------------------------------------------------! 1743 ! Description: 1744 ! ------------ 1745 !> Calculate the coefficient matrix from the Lund rotation. 1746 !------------------------------------------------------------------------------! 1747 SUBROUTINE calc_coeff_matrix 1748 1749 IMPLICIT NONE 1750 1751 INTEGER(iwp) :: k !< loop index in z-direction 1752 1753 ! 1754 !-- Calculate coefficient matrix. Split loops to allow for loop vectorization. 1755 DO k = nzb+1, nzt+1 1756 IF ( r11(k) > 0.0_wp ) THEN 1757 a11(k) = SQRT( r11(k) ) 1758 a21(k) = r21(k) / a11(k) 1759 a31(k) = r31(k) / a11(k) 1760 ELSE 1761 a11(k) = 10E-8_wp 1762 a21(k) = 10E-8_wp 1763 a31(k) = 10E-8_wp 1764 ENDIF 1765 ENDDO 1766 DO k = nzb+1, nzt+1 1767 a22(k) = r22(k) - a21(k)**2 1768 IF ( a22(k) > 0.0_wp ) THEN 1769 a22(k) = SQRT( a22(k) ) 1770 a32(k) = r32(k) - a21(k) * a31(k) / a22(k) 1771 ELSE 1772 a22(k) = 10E-8_wp 1773 a32(k) = 10E-8_wp 1774 ENDIF 1775 ENDDO 1776 DO k = nzb+1, nzt+1 1777 a33(k) = r33(k) - a31(k)**2 - a32(k)**2 1778 IF ( a33(k) > 0.0_wp ) THEN 1779 a33(k) = SQRT( a33(k) ) 1780 ELSE 1781 a33(k) = 10E-8_wp 1782 ENDIF 1783 ENDDO 1784 ! 1785 !-- Set bottom boundary condition 1786 a11(nzb) = a11(nzb+1) 1787 a22(nzb) = a22(nzb+1) 1788 a21(nzb) = a21(nzb+1) 1789 a33(nzb) = a33(nzb+1) 1790 a31(nzb) = a31(nzb+1) 1791 a32(nzb) = a32(nzb+1) 1792 1793 END SUBROUTINE calc_coeff_matrix 1794 1795 !------------------------------------------------------------------------------! 1796 ! Description: 1797 ! ------------ 1798 !> This routine controls the re-adjustment of the turbulence statistics used 1799 !> for generating turbulence at the lateral boundaries. 1800 !------------------------------------------------------------------------------! 1801 SUBROUTINE stg_adjust 1802 1803 IMPLICIT NONE 1804 1805 INTEGER(iwp) :: k 1806 1807 CALL cpu_log( log_point(57), 'synthetic_turbulence_gen', 'start' ) 1808 ! 1809 !-- Compute mean boundary layer height according to Richardson-Bulk 1810 !-- criterion using the inflow profiles. Further velocity scale as well as 1811 !-- mean friction velocity are calculated. 1812 CALL calc_scaling_variables 1813 ! 1814 !-- Set length and time scales depending on boundary-layer height 1815 CALL calc_length_and_time_scale 1816 ! 1817 !-- Parametrize Reynolds-stress tensor, diagonal elements as well 1818 !-- as r21 (v'u'), r31 (w'u'), r32 (w'v'). Parametrization follows 1819 !-- Rotach et al. (1996) and is based on boundary-layer depth, 1820 !-- friction velocity and velocity scale. 1821 CALL parametrize_reynolds_stress 1822 ! 1823 !-- Calculate coefficient matrix from Reynolds stress tensor 1824 !-- (Lund rotation) 1825 CALL calc_coeff_matrix 1826 ! 1827 !-- Determine filter functions on basis of updated length scales 1828 CALL stg_filter_func( nux, bux ) !filter ux 1829 CALL stg_filter_func( nuy, buy ) !filter uy 1830 CALL stg_filter_func( nuz, buz ) !filter uz 1831 CALL stg_filter_func( nvx, bvx ) !filter vx 1832 CALL stg_filter_func( nvy, bvy ) !filter vy 1833 CALL stg_filter_func( nvz, bvz ) !filter vz 1834 CALL stg_filter_func( nwx, bwx ) !filter wx 1835 CALL stg_filter_func( nwy, bwy ) !filter wy 1836 CALL stg_filter_func( nwz, bwz ) !filter wz 1837 ! 1838 !-- Reset time counter for controlling next adjustment to zero 1839 time_stg_adjust = 0.0_wp 1840 1841 CALL cpu_log( log_point(57), 'synthetic_turbulence_gen', 'stop' ) 1842 1843 END SUBROUTINE stg_adjust 1844 1845 1846 !------------------------------------------------------------------------------! 1847 ! Description: 1848 ! ------------ 1849 !> Calculates turbuluent length and time scales if these are not available 1850 !> from measurements. 1851 !------------------------------------------------------------------------------! 1852 SUBROUTINE calc_length_and_time_scale 1853 1854 USE arrays_3d, & 1855 ONLY: dzw, ddzw, u_init, v_init, zu, zw 1856 1857 USE grid_variables, & 1858 ONLY: ddx, ddy, dx, dy 1859 1860 USE statistics, & 1861 ONLY: hom 1862 1863 IMPLICIT NONE 1864 1865 1866 INTEGER(iwp) :: k !< loop index in z-direction 1867 1868 REAL(wp) :: length_scale !< typical length scale 1869 1870 ! 1871 !-- In initial call the boundary-layer depth can be zero. This case, set 1872 !-- minimum value for boundary-layer depth, to setup length scales correctly. 1873 zi_ribulk = MAX( zi_ribulk, zw(nzb+2) ) 1874 ! 1875 !-- Set-up default turbulent length scales. From the numerical point of 1876 !-- view the imposed perturbations should not be immediately dissipated 1877 !-- by the numerics. The numerical dissipation, however, acts on scales 1878 !-- up to 8 x the grid spacing. For this reason, set the turbulence 1879 !-- length scale to 8 time the grid spacing. Further, above the boundary 1880 !-- layer height, set turbulence lenght scales to zero (equivalent to not 1881 !-- imposing any perturbations) in order to save computational costs. 1882 !-- Typical time scales are derived by assuming Taylors's hypothesis, 1883 !-- using the length scales and the mean profiles of u- and v-component. 1884 DO k = nzb+1, nzt+1 1885 1886 length_scale = 8.0_wp * MIN( dx, dy, dzw(k) ) 1887 1888 IF ( zu(k) <= zi_ribulk ) THEN 1889 ! 1890 !-- Assume isotropic turbulence length scales 1891 nux(k) = MAX( INT( length_scale * ddx ), 1 ) 1892 nuy(k) = MAX( INT( length_scale * ddy ), 1 ) 1893 nuz(k) = MAX( INT( length_scale * ddzw(k) ), 1 ) 1894 nvx(k) = MAX( INT( length_scale * ddx ), 1 ) 1895 nvy(k) = MAX( INT( length_scale * ddy ), 1 ) 1896 nvz(k) = MAX( INT( length_scale * ddzw(k) ), 1 ) 1897 nwx(k) = MAX( INT( length_scale * ddx ), 1 ) 1898 nwy(k) = MAX( INT( length_scale * ddy ), 1 ) 1899 nwz(k) = MAX( INT( length_scale * ddzw(k) ), 1 ) 1900 ! 1901 !-- Limit time scales, else they become very larger for low wind speed, 1902 !-- imposing long-living inflow perturbations which in turn propagate 1903 !-- further into the model domain. Use u_init and v_init to calculate 1904 !-- the time scales, which will be equal to the inflow profiles, both, 1905 !-- in offline nesting mode or in dirichlet/radiation mode. 1906 tu(k) = MIN( dt_stg_adjust, length_scale / & 1907 ( ABS( u_init(k) ) + 0.1_wp ) ) 1908 tv(k) = MIN( dt_stg_adjust, length_scale / & 1909 ( ABS( v_init(k) ) + 0.1_wp ) ) 1910 ! 1911 !-- Time scale of w-component is a mixture from u- and v-component. 1912 tw(k) = SQRT( tu(k)**2 + tv(k)**2 ) 1913 ! 1914 !-- Above the boundary layer length scales are zero, i.e. imposed turbulence 1915 !-- is not correlated in space and time, just white noise. This saves 1916 !-- computations power. 1917 ELSE 1918 nux(k) = 0.0_wp 1919 nuy(k) = 0.0_wp 1920 nuz(k) = 0.0_wp 1921 nvx(k) = 0.0_wp 1922 nvy(k) = 0.0_wp 1923 nvz(k) = 0.0_wp 1924 nwx(k) = 0.0_wp 1925 nwy(k) = 0.0_wp 1926 nwz(k) = 0.0_wp 1927 1928 tu(k) = 0.0_wp 1929 tv(k) = 0.0_wp 1930 tw(k) = 0.0_wp 1931 ENDIF 1932 ENDDO 1933 ! 1934 !-- Set bottom boundary condition for the length and time scales 1935 nux(nzb) = nux(nzb+1) 1936 nuy(nzb) = nuy(nzb+1) 1937 nuz(nzb) = nuz(nzb+1) 1938 nvx(nzb) = nvx(nzb+1) 1939 nvy(nzb) = nvy(nzb+1) 1940 nvz(nzb) = nvz(nzb+1) 1941 nwx(nzb) = nwx(nzb+1) 1942 nwy(nzb) = nwy(nzb+1) 1943 nwz(nzb) = nwz(nzb+1) 1944 1945 tu(nzb) = tu(nzb+1) 1946 tv(nzb) = tv(nzb+1) 1947 tw(nzb) = tw(nzb+1) 1948 1949 1950 END SUBROUTINE calc_length_and_time_scale 1951 1952 !------------------------------------------------------------------------------! 1953 ! Description: 1954 ! ------------ 1955 !> Calculate scaling variables which are used for turbulence parametrization 1956 !> according to Rotach et al. (1996). Scaling variables are: friction velocity, 1957 !> boundary-layer depth, momentum velocity scale, and Obukhov length. 1958 !------------------------------------------------------------------------------! 1959 SUBROUTINE calc_scaling_variables 1960 1961 1962 USE control_parameters, & 1963 ONLY: bc_dirichlet_l, bc_dirichlet_n, bc_dirichlet_r, bc_dirichlet_s, & 1964 humidity, pt_surface 1965 1966 USE indices, & 1967 ONLY: nx, ny 1968 1969 USE surface_mod, & 1970 ONLY: surf_def_h, surf_lsm_h, surf_usm_h 1971 1972 IMPLICIT NONE 1973 1974 INTEGER(iwp) :: i !< loop index in x-direction 1975 INTEGER(iwp) :: j !< loop index in y-direction 1976 INTEGER(iwp) :: k !< loop index in z-direction 1977 INTEGER(iwp) :: k_ref !< index in z-direction for reference height 1978 INTEGER(iwp) :: m !< surface element index 1979 1980 REAL(wp) :: friction_vel_l !< mean friction veloctiy on subdomain 1981 REAL(wp) :: shf_mean !< mean surface sensible heat flux 1982 REAL(wp) :: shf_mean_l !< mean surface sensible heat flux on subdomain 1983 REAL(wp) :: u_int !< u-component 1984 REAL(wp) :: v_int !< v-component 1985 REAL(wp) :: vpt_surface !< near-surface virtual potential temperature 1986 REAL(wp) :: w_convective !< convective velocity scale 1987 REAL(wp) :: z0_mean !< mean roughness length 1988 REAL(wp) :: z0_mean_l !< mean roughness length on subdomain 1989 1990 ! 1991 !-- Mean friction velocity and velocity scale. Therefore, 1992 !-- pre-calculate mean roughness length and surface sensible heat flux 1993 !-- in the model domain, which are further used to estimate friction 1994 !-- velocity and velocity scale. Note, for z0 linear averaging is applied, 1995 !-- even though this is known to unestimate the effective roughness. 1996 !-- This need to be revised later. 1997 z0_mean_l = 0.0_wp 1998 shf_mean_l = 0.0_wp 1999 DO m = 1, surf_def_h(0)%ns 2000 z0_mean_l = z0_mean_l + surf_def_h(0)%z0(m) 2001 shf_mean_l = shf_mean_l + surf_def_h(0)%shf(m) 2002 ENDDO 2003 DO m = 1, surf_lsm_h%ns 2004 z0_mean_l = z0_mean_l + surf_lsm_h%z0(m) 2005 shf_mean_l = shf_mean_l + surf_lsm_h%shf(m) 2006 ENDDO 2007 DO m = 1, surf_usm_h%ns 2008 z0_mean_l = z0_mean_l + surf_usm_h%z0(m) 2009 shf_mean_l = shf_mean_l + surf_usm_h%shf(m) 2010 ENDDO 2011 2012 #if defined( __parallel ) 2013 CALL MPI_ALLREDUCE( z0_mean_l, z0_mean, 1, MPI_REAL, MPI_SUM, & 2014 comm2d, ierr ) 2015 CALL MPI_ALLREDUCE( shf_mean_l, shf_mean, 1, MPI_REAL, MPI_SUM, & 2016 comm2d, ierr ) 2017 #else 2018 z0_mean = z0_mean_l 2019 shf_mean = shf_mean_l 2020 #endif 2021 z0_mean = z0_mean / REAL( ( nx + 1 ) * ( ny + 1 ), KIND = wp ) 2022 shf_mean = shf_mean / REAL( ( nx + 1 ) * ( ny + 1 ), KIND = wp ) 2023 2024 ! 2025 !-- Note, Inifor does not use logarithmic interpolation of the 2026 !-- velocity components near the ground, so that near-surface 2027 !-- wind speed and thus the friction velocity is overestimated. 2028 !-- However, friction velocity is used for turbulence 2029 !-- parametrization, so that more physically meaningful values are important. 2030 !-- Hence, derive friction velocity from wind speed at a reference height. 2031 !-- For a first guess use 20 m, which is in the range of the first 2032 !-- COSMO vertical level. 2033 k_ref = MINLOC( ABS( zu - cosmo_ref ), DIM = 1 ) - 1 2034 2035 friction_vel_l = 0.0_wp 2036 IF ( bc_dirichlet_l .OR. bc_dirichlet_r ) THEN 2037 2038 i = MERGE( -1, nxr + 1, bc_dirichlet_l ) 2039 2040 DO j = nys, nyn 2041 ! 2042 !-- Note, in u- and v- component the imposed perturbations 2043 !-- from the STG are already included. Check whether this 2044 !-- makes any difference compared to using the pure-mean 2045 !-- inflow profiles. 2046 u_int = MERGE( u(k_ref,j,i+1), u(k_ref,j,i), bc_dirichlet_l ) 2047 v_int = v(k_ref,j,i) 2048 ! 2049 !-- Calculate friction velocity and sum-up. Therefore, assume 2050 !-- neutral condtions. 2051 friction_vel_l = friction_vel_l + kappa * & 2052 SQRT( u_int * u_int + v_int * v_int ) / & 2053 LOG( zu(k_ref) / z0_mean ) 2054 2055 ENDDO 2056 2057 ENDIF 2058 2059 IF ( bc_dirichlet_s .OR. bc_dirichlet_n ) THEN 2060 2061 j = MERGE( -1, nyn + 1, bc_dirichlet_s ) 2062 2063 DO i = nxl, nxr 2064 2065 u_int = u(k_ref,j,i) 2066 v_int = MERGE( v(k_ref,j+1,i), v(k_ref,j,i), bc_dirichlet_s ) 2067 2068 friction_vel_l = friction_vel_l + kappa * & 2069 SQRT( u_int * u_int + v_int * v_int ) / & 2070 LOG( zu(k_ref) / z0_mean ) 2071 2072 ENDDO 2073 2074 ENDIF 2075 2076 #if defined( __parallel ) 2077 CALL MPI_ALLREDUCE( friction_vel_l, scale_us, 1, MPI_REAL, MPI_SUM, & 2078 comm2d, ierr ) 2079 #else 2080 scale_us = friction_vel_l 2081 #endif 2082 scale_us = scale_us / REAL( 2 * nx + 2 * ny, KIND = wp ) 2083 2084 ! 2085 !-- Compute mean Obukhov length 2086 IF ( shf_mean > 0.0_wp ) THEN 2087 scale_l = - pt_surface / ( kappa * g ) * scale_us**3 / shf_mean 2088 ELSE 2089 scale_l = 0.0_wp 2090 ENDIF 2091 2092 ! 2093 !-- Compute mean convective velocity scale. Note, in case the mean heat flux 2094 !-- is negative, set convective velocity scale to zero. 2095 IF ( shf_mean > 0.0_wp ) THEN 2096 w_convective = ( g * shf_mean * zi_ribulk / pt_surface )**( 1.0_wp / 3.0_wp ) 2097 ELSE 2098 w_convective = 0.0_wp 2099 ENDIF 2100 ! 2101 !-- Finally, in order to consider also neutral or stable stratification, 2102 !-- compute momentum velocity scale from u* and convective velocity scale, 2103 !-- according to Rotach et al. (1996). 2104 scale_wm = ( scale_us**3 + 0.6_wp * w_convective**3 )**( 1.0_wp / 3.0_wp ) 2105 2106 END SUBROUTINE calc_scaling_variables 2107 1714 2108 END MODULE synthetic_turbulence_generator_mod -
palm/trunk/SOURCE/time_integration.f90
r3298 r3347 25 25 ! ----------------- 26 26 ! $Id$ 27 ! - offline nesting separated from large-scale forcing module 28 ! - changes for synthetic turbulence generator 29 ! 30 ! 3343 2018-10-15 10:38:52Z suehring 27 31 ! - Formatting, clean-up, comments (kanani) 28 32 ! - Added CALL to chem_emissions_setup (Russo) … … 459 463 460 464 USE lsf_nudging_mod, & 461 ONLY: calc_tnudge, ls_forcing_surf, ls_forcing_vert, nudge_ref, & 462 lsf_nesting_offline, lsf_nesting_offline_mass_conservation 465 ONLY: calc_tnudge, ls_forcing_surf, ls_forcing_vert, nudge_ref 463 466 464 467 USE multi_agent_system_mod, & 465 468 ONLY: agents_active, multi_agent_system 466 469 470 USE nesting_offl_mod, & 471 ONLY: nesting_offl_bc, nesting_offl_mass_conservation 472 467 473 USE netcdf_data_input_mod, & 468 ONLY: chem_emis, chem_emis_att, nest_offl, netcdf_data_input_lsf 474 ONLY: chem_emis, chem_emis_att, nest_offl, & 475 netcdf_data_input_offline_nesting 469 476 470 477 USE ocean_mod, & … … 515 522 516 523 USE synthetic_turbulence_generator_mod, & 517 ONLY: stg_main, use_syn_turb_gen 524 ONLY: dt_stg_call, dt_stg_adjust, parametrize_inflow_turbulence, & 525 stg_adjust, stg_main, time_stg_adjust, time_stg_call, & 526 use_syn_turb_gen 518 527 519 528 USE user_actions_mod, & … … 638 647 IF ( nesting_offline ) THEN 639 648 IF ( nest_offl%time(nest_offl%tind_p) <= time_since_reference_point )& 640 CALL netcdf_data_input_ lsf649 CALL netcdf_data_input_offline_nesting 641 650 ENDIF 642 651 … … 918 927 !-- Impose a turbulent inflow using the recycling method 919 928 IF ( turbulent_inflow ) CALL inflow_turbulence 920 921 !922 !-- Impose a turbulent inflow using synthetic generated turbulence923 IF ( use_syn_turb_gen ) CALL stg_main924 929 925 930 ! … … 960 965 !-- boundaries. 961 966 IF ( nesting_offline .AND. intermediate_timestep_count == & 962 intermediate_timestep_count_max ) THEN 963 CALL lsf_nesting_offline 964 ! 965 !-- Moreover, ensure mass conservation 966 CALL lsf_nesting_offline_mass_conservation 967 ENDIF 968 967 intermediate_timestep_count_max ) & 968 CALL nesting_offl_bc 969 ! 970 !-- Impose a turbulent inflow using synthetic generated turbulence, 971 !-- only once per time step. 972 IF ( use_syn_turb_gen .AND. time_stg_call >= dt_stg_call .AND. & 973 intermediate_timestep_count == intermediate_timestep_count_max ) THEN! & 974 CALL stg_main 975 ENDIF 976 ! 977 !-- Ensure mass conservation. This need to be done after imposing 978 !-- synthetic turbulence and top boundary condition for pressure is set to 979 !-- Neumann conditions. 980 !-- Is this also required in case of Dirichlet? 981 IF ( nesting_offline ) CALL nesting_offl_mass_conservation 969 982 ! 970 983 !-- Reduce the velocity divergence via the equation for perturbation … … 1213 1226 time_dopr_listing = time_dopr_listing + dt_3d 1214 1227 time_run_control = time_run_control + dt_3d 1228 ! 1229 !-- In case of synthetic turbulence generation and parametrized turbulence 1230 !-- information, update the time counter and if required, adjust the 1231 !-- STG to new atmospheric conditions. 1232 IF ( use_syn_turb_gen ) THEN 1233 IF ( parametrize_inflow_turbulence ) THEN 1234 time_stg_adjust = time_stg_adjust + dt_3d 1235 IF ( time_stg_adjust >= dt_stg_adjust ) CALL stg_adjust 1236 ENDIF 1237 time_stg_call = time_stg_call + dt_3d 1238 ENDIF 1215 1239 1216 1240 ! … … 1472 1496 1473 1497 ENDDO ! time loop 1474 1498 1499 ! 1475 1500 !-- Vertical nesting: Deallocate variables initialized for vertical nesting 1476 1501 IF ( vnest_init ) CALL vnest_deallocate -
palm/trunk/SOURCE/urban_surface_mod.f90
r3337 r3347 28 28 ! ----------------- 29 29 ! $Id$ 30 ! Enable USM initialization with default building parameters in case no static 31 ! input file exist. 32 ! 33 ! 3343 2018-10-15 10:38:52Z suehring 30 34 ! Add output variables usm_rad_pc_inlw, usm_rad_pc_insw* 31 35 ! … … 6902 6906 INTEGER(iwp) :: wtc 6903 6907 REAL(wp), DIMENSION(n_surface_params) :: wtp 6908 6909 LOGICAL :: ascii_file = .FALSE. 6904 6910 6905 6911 INTEGER(iwp), DIMENSION(0:17, nysg:nyng, nxlg:nxrg) :: usm_par … … 6922 6928 IF ( building_type_f%from_file .OR. building_pars_f%from_file ) & 6923 6929 RETURN 6930 ! 6931 !-- Check if ASCII input file exists. If not, return and initialize USM 6932 !-- with default settings. 6933 INQUIRE( FILE = 'SURFACE_PARAMETERS' // coupling_char, & 6934 EXIST = ascii_file ) 6935 6936 IF ( .NOT. ascii_file ) RETURN 6924 6937 6925 6938 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Note: See TracChangeset
for help on using the changeset viewer.