3 !***********************************************************************
5 ! Purpose: Stochastic Perturbation Schemes
6 ! Author : Judith Berner, NCAR (berner@ucar.edu)
9 !***********************************************************************
11 ! The scheme introduces stochastic perturbations to the rotational wind
12 ! components and to the potential temperature field. The stochastic
13 ! perturbations are generated by independent autoregressive processes for
14 ! each wavenumber and results in smooth spatially and temporally correlated patterns.
15 ! Details of the scheme and its performance in a meso-scale WRF-ensemble
16 ! system are available in:
18 ! Berner, J., S.-Y. Ha, J. P. Hacker, A. Fournier and C. Snyder 2011:
19 ! "Model uncertainty in a mesoscale ensemble prediction system: Stochastic
20 ! versus multi-physics representations", 2011, Mon. Wea. Rev., 139, 1972-1995
21 ! http://journals.ametsoc.org/doi/abs/10.1175/2010MWR3595.1
24 ! Dissipation: Dissipation rates are assumed constant in space and time
25 ! Vertical structure: Supports two options for vertical structure:
29 ! Optional namelist parameters:
30 ! stoch_force_opt = 0, 0, 0: No stochastic parameterization
31 ! = 1, 1, 1: Use SKEB scheme
32 ! skebs_vertstruc = 0, 0, 0: Constant vertical structure of random pattern generator
33 ! = 1, 1, 1: Random phase vertical structure random pattern generator
34 ! tot_backscat_psi : Total backscattered dissipation rate for streamfunction; Controls
35 ! amplitude of rotational wind perturbations Default value is 1.0E-5 m2/s3.
36 ! tot_backscat_t : Total backscattered dissipation rate for potential temperature;
37 ! Controls amplitude of potential temperature perturbations. Default value is 1.0E-6 m2/s3.
38 ! nens : Random seed for random number stream. This parameter needs to be different
39 ! for each member in ensemble forecasts. Is a function of initial start time
40 ! to ensure different random number streams for different forecasts.
41 ! ztau_psi : Decorrelation time (in s) for streamfunction perturbations.
42 ! Default is 10800s. Recommended value is 216000s.
43 ! ztau_t : Decorrelation time (in s) for potential temperature perturbations.
44 ! Default 10800s. Recommended value is 216000s.
45 ! rexponent_psi : Spectral slope for streamfunction perturbations. Default is -1.83
46 ! for a kinetic-energy forcing spectrum with slope -5/3.
47 ! rexponent_t : Spectral slope of potential temperature perturbations. Default is -1.83
48 ! for a potential energy forcing spectrum with slope -1.832.
49 ! kminforc : Minimal forcing wavenumber in longitude for streamfunction perturbations. Default is 1.
50 ! lminforc : Minimal forcing wavenumber in latitude for streamfunction perturbations. Default is 1.
51 ! kminforc : Minimal forcing wavenumber in longitude for potential temperature perturbations. Default is 1.
52 ! lminforct : Minimal forcing wavenumber in latitude for potential temperature perturbations. Default is 1.
53 ! kmaxforc : Maximal forcing wavenumber in longitude for streamfunction perturbations.
54 ! Default is maximal possible wavenumbers determined by number of gridpoints.
55 ! lmaxforc : Maximal forcing wavenumber in latitude for streamfunction perturbations.
56 ! Default is maximal possible wavenumbers determined by number of gridpoints.
57 ! kmaxforct : Maximal forcing wavenumber in longitude for potential temperature perturbations.
58 ! Default is maximal possible wavenumbers determined by number of gridpoints.
59 ! lmaxforct : Maximal forcing wavenumber in latitude for potential temperature perturbations.
60 ! Default is maximal possible wavenumbers determined by number of gridpoints.
61 ! zsigma2_eps : Noise variance in autoregressive process defining streamfunction perturbations.
62 ! zsigma2_eta : Noise variance in autoregressive process defining in potential temperature perturbations.
64 !***********************************************************************
65 ! ------------------------------------------------------------------
66 !************** DECLARE FIELDS AND VARIABLES FOR STOCHASTIC BACKSCATTER
67 ! ------------------------------------------------------------------
69 public :: SETUP_RAND_PERTURB, UPDATE_STOCH,&
70 do_fftback_along_x,do_fftback_along_y,&
73 INTEGER :: LMINFORC, LMAXFORC, KMINFORC, KMAXFORC, &
74 & LMINFORCT, LMAXFORCT, KMINFORCT, KMAXFORCT
75 REAL :: ALPH, ALPH_PSI, ALPH_T, TOT_BACKSCAT_PSI, TOT_BACKSCAT_T, REXPONENT_PSI,REXPONENT_T
77 ! ----------Fields for spectral transform -----------
80 INTEGER,ALLOCATABLE:: wavenumber_k(:), wavenumber_l(:)
81 REAL, ALLOCATABLE :: WSAVE1(:),WSAVE2(:)
83 ! --------- Others -------------------------------------------------
84 REAL, PARAMETER:: RPI= 3.141592653589793 !4.0*atan(1.0)
85 REAL, PARAMETER:: CP= 1006.0 ! specific heat of dry air in J/(Kg*K)= m^2/(K* s^2)
86 REAL, PARAMETER:: T0= 300.0 ! Reference temperature in K
91 !=======================================================================
93 !=======================================================================
94 ! ------------------------------------------------------------------
95 !!************** INITIALIZE STOCHASTIC ROUTINES *****************************
96 ! ------------------------------------------------------------------
97 ! This subroutine drives the initialization of the stochastic schemes
99 SUBROUTINE INITIALIZE_STOCH (grid, config_flags, &
100 first_trip_for_this_domain, &
101 ips, ipe, jps, jpe, kps, kpe, &
102 ids, ide, jds, jde, kds, kde, &
103 ims, ime, jms, jme, kms, kme, &
104 its, ite, jts, jte, kts, kte, &
105 imsx, imex, jmsx, jmex, kmsx, kmex, &
106 ipsx, ipex, jpsx, jpex, kpsx, kpex, &
107 imsy, imey, jmsy, jmey, kmsy, kmey, &
108 ipsy, ipey, jpsy, jpey, kpsy, kpey )
113 USE module_domain, ONLY : domain
116 USE module_dm, ONLY : local_communicator, mytask, ntasks, ntasks_x, ntasks_y, local_communicator_periodic, &
117 wrf_dm_maxval, wrf_err_message, local_communicator_x, local_communicator_y, data_order_xzy
122 TYPE (grid_config_rec_type) :: config_flags
123 TYPE ( domain ), INTENT(INOUT) :: grid
125 INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde, &
126 ims, ime, jms, jme, kms, kme, &
127 ips, ipe, jps, jpe, kps, kpe, &
128 its, ite, jts, jte, kts, kte
129 INTEGER , INTENT(IN) :: imsx,imex,jmsx,jmex,kmsx,kmex, &
130 ipsx,ipex,jpsx,jpex,kpsx,kpex, &
131 imsy,imey,jmsy,jmey,kmsy,kmey, &
132 ipsy,ipey,jpsy,jpey,kpsy,kpey
134 LOGICAL :: first_trip_for_this_domain
135 INTEGER :: K, n, nfield, ierr, iseed, vertstruc, kvar
136 real :: std, lengthscale, timescale, std_cutoff
137 character (len = 10) :: varname
138 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
139 INTEGER :: stochpert_unit
140 INTEGER , PARAMETER :: OPEN_OK = 0
141 CHARACTER (len = 1024) :: message
142 logical, parameter :: DEBUG_MULTI_PERT = .true.
143 REAL, DIMENSION(ims:ime,jms:jme) :: SPFORCS3d_loc, SPFORCC3d_loc, SP_AMP3d_loc
146 IF ( first_trip_for_this_domain ) THEN
147 grid%did_stoch = .FALSE.
150 IF ((( grid%id == 1) .AND. (.NOT. grid%did_stoch)) .AND. &
151 (( grid%skebs_on== 1) .OR.( grid%sppt_on== 1) .OR. ( grid%rand_perturb_on== 1) .OR. &
152 ( grid%spp_conv== 1) .OR. ( grid%spp_pbl== 1) .OR. ( grid%spp_lsm== 1)) .or. &
153 (config_flags%multi_perturb == 1)) THEN
155 grid%did_stoch = .TRUE.
157 IF (grid%skebs_on==1) then
160 ! Initialize streamfunction (1)
161 if ((.not.config_flags%restart) .or. (.not.config_flags%hrrr_cycling)) then
162 call rand_seed (config_flags, grid%ISEED_SKEBS, grid%iseedarr_skebs , 1, config_flags%seed_dim)
164 call SETUP_RAND_PERTURB('W', &
165 grid%skebs_vertstruc,config_flags%restart, &
167 grid%SPSTREAMFORCS,grid%SPSTREAMFORCC,grid%ALPH_PSI,&
168 grid%VERTSTRUCC,grid%VERTSTRUCS,grid%VERTAMPUV, &
169 grid%KMINFORCT,grid%KMAXFORCT, &
170 grid%LMINFORCT,grid%LMAXFORCT, &
171 grid%KMAXFORCTH,grid%LMAXFORCTH, &
172 grid%time_step,grid%DX,grid%DY, &
173 grid%gridpt_stddev_sppt, &
174 grid%lengthscale_sppt, &
175 grid%timescale_sppt, &
176 grid%TOT_BACKSCAT_PSI,grid%ZTAU_PSI, &
177 grid%REXPONENT_PSI, &
178 ids, ide, jds, jde, kds, kde, &
179 ims, ime, jms, jme, kms, kme, &
180 its, ite, jts, jte, kts, kte )
181 ! Initialize potential temperature (2)
182 call SETUP_RAND_PERTURB('T', &
183 grid%skebs_vertstruc,config_flags%restart, &
185 grid%SPTFORCS,grid%SPTFORCC,grid%ALPH_T, &
186 grid%VERTSTRUCC,grid%VERTSTRUCS,grid%VERTAMPT, &
187 grid%KMINFORCT,grid%KMAXFORCT, &
188 grid%LMINFORCT,grid%LMAXFORCT, &
189 grid%KMAXFORCTH,grid%LMAXFORCTH, &
190 grid%time_step,grid%DX,grid%DY, &
191 grid%gridpt_stddev_sppt, &
192 grid%lengthscale_sppt, &
193 grid%timescale_sppt, &
194 grid%TOT_BACKSCAT_T,grid%ZTAU_T, &
196 ids, ide, jds, jde, kds, kde, &
197 ims, ime, jms, jme, kms, kme, &
198 its, ite, jts, jte, kts, kte )
201 IF (grid%sppt_on==1) then
202 ! Initialize SPPT (3)
203 if ((.not.config_flags%restart) .or. (.not.config_flags%hrrr_cycling)) then
204 call rand_seed (config_flags, grid%ISEED_SPPT, grid%iseedarr_sppt , 1, config_flags%seed_dim)
206 call SETUP_RAND_PERTURB('P', &
207 grid%sppt_vertstruc,config_flags%restart, &
209 grid%SPPTFORCC,grid%SPPTFORCS,grid%ALPH_SPPT, &
210 grid%VERTSTRUCC,grid%VERTSTRUCS,grid%VERTAMPT, &
211 grid%KMINFORCT,grid%KMAXFORCT, &
212 grid%LMINFORCT,grid%LMAXFORCT, &
213 grid%KMAXFORCTH,grid%LMAXFORCTH, &
214 grid%time_step,grid%DX,grid%DY, &
215 grid%gridpt_stddev_sppt, &
216 grid%lengthscale_sppt, &
217 grid%timescale_sppt, &
218 grid%TOT_BACKSCAT_PSI,grid%ZTAU_PSI, &
219 grid%REXPONENT_PSI, &
220 ids, ide, jds, jde, kds, kde, &
221 ims, ime, jms, jme, kms, kme, &
222 its, ite, jts, jte, kts, kte )
225 ! Initialize RAND_PERTURB (4)
226 IF (grid%rand_perturb_on==1) then
227 if ((.not.config_flags%restart) .or. (.not.config_flags%hrrr_cycling)) then
228 call rand_seed (config_flags, grid%ISEED_RAND_PERT, grid%iseedarr_rand_pert , 1, config_flags%seed_dim)
230 call SETUP_RAND_PERTURB('R', &
231 grid%rand_pert_vertstruc,config_flags%restart, &
233 grid%SPFORCC,grid%SPFORCS,grid%ALPH_RAND, &
234 grid%VERTSTRUCC,grid%VERTSTRUCS,grid%VERTAMPT, &
235 grid%KMINFORCT,grid%KMAXFORCT, &
236 grid%LMINFORCT,grid%LMAXFORCT, &
237 grid%KMAXFORCTH,grid%LMAXFORCTH, &
238 grid%time_step,grid%DX,grid%DY, &
239 grid%gridpt_stddev_rand_pert, &
240 grid%lengthscale_rand_pert, &
241 grid%timescale_rand_pert, &
242 grid%TOT_BACKSCAT_PSI,grid%ZTAU_PSI, &
243 grid%REXPONENT_PSI, &
244 ids, ide, jds, jde, kds, kde, &
245 ims, ime, jms, jme, kms, kme, &
246 its, ite, jts, jte, kts, kte )
248 if (.not.config_flags%restart) then ! spin up
250 CALL RAND_PERT_UPDATE(grid,'R', &
251 grid%SPFORCS,grid%SPFORCC, &
252 grid%SP_AMP,grid%ALPH_RAND, &
253 ips, ipe, jps, jpe, kps, kpe, &
254 ids, ide, jds, jde, kds, kde, &
255 ims, ime, jms, jme, kms, kme, &
257 imsx,imex,jmsx,jmex,kmsx,kmex, &
258 ipsx,ipex,jpsx,jpex,kpsx,kpex, &
259 imsy,imey,jmsy,jmey,kmsy,kmey, &
260 ipsy,ipey,jpsy,jpey,kpsy,kpey, &
261 grid%num_stoch_levels,grid%num_stoch_levels, &
262 grid%num_stoch_levels,grid%num_stoch_levels, &
263 config_flags%restart, grid%iseedarr_rand_pert, &
264 config_flags%seed_dim, &
265 grid%DX,grid%DY,grid%rand_pert_vertstruc, &
267 grid%stddev_cutoff_rand_pert, &
268 grid%gridpt_stddev_rand_pert, &
269 grid%VERTSTRUCC,grid%VERTSTRUCS,grid%VERTAMPT )
271 ENDIF !rand_perturb_on
274 ! Initialize MULTI_PERTURB
275 If_multi_perturb: IF (config_flags%multi_perturb == 1) then
276 ! Set frequency to update perturbations: spdt is in min and dt is in s
277 grid%stepsp = nint (config_flags%spdt * 60.0 / grid%dt)
278 grid%stepsp = max (grid%stepsp, 1)
280 ! Initialize perturbations
282 IF ( wrf_dm_on_monitor() ) THEN
283 OPEN(stochpert_unit, FILE='STOCHPERT.TBL',FORM='FORMATTED',STATUS='OLD',IOSTAT=ierr)
284 IF ( ierr .NE. OPEN_OK ) THEN
285 WRITE(message,FMT='(A)') &
286 'module_stoch.F: INITIALIZE_STOCH: open failure for STOCHPERT.TBL'
287 CALL wrf_error_fatal ( message )
289 REWIND(stochpert_unit)
292 if (DEBUG_MULTI_PERT) print *, 'num_pert3d = ', num_pert3d
293 if (DEBUG_MULTI_PERT) print *, 'num_pert_3d = ', config_flags%num_pert_3d
295 if ( wrf_dm_on_monitor() ) then
296 READ (stochpert_unit,*) ! Skip
297 READ (stochpert_unit,*) ! the
298 READ (stochpert_unit,*) ! header
300 DO n = 2, config_flags%num_pert_3d
301 IF ( wrf_dm_on_monitor() ) THEN
302 read (stochpert_unit, *) nfield, varname, std, lengthscale, timescale, std_cutoff, &
304 select case (trim(varname))
348 WRITE(message,FMT='(A)') &
349 'module_stoch.F: Invalid entry in STOCHPERT.TBL'
350 CALL wrf_error_fatal ( message )
354 grid%gridpt_stddev_mult3d(kvar) = std
355 grid%lengthscale_mult3d(kvar) = lengthscale
356 grid%timescale_mult3d(kvar) = timescale
357 grid%stddev_cutoff_mult3d(kvar) = std_cutoff
358 grid%ISEED_MULT3D(kvar) = iseed
359 grid%mult3d_vertstruc(kvar) = vertstruc
361 if (DEBUG_MULTI_PERT) print *, kvar, varname, grid%gridpt_stddev_mult3d(kvar), &
362 grid%lengthscale_mult3d(kvar), grid%timescale_mult3d(kvar), &
363 grid%stddev_cutoff_mult3d(kvar), grid%ISEED_MULT3D(kvar), &
364 grid%mult3d_vertstruc(kvar)
366 ! Note that num_pert_3d is the dimension of the 1d arrays from the table
367 ! and num_pert3d is the number of allocated pert3d elements from the package (<= num_pert_3d)
368 CALL wrf_dm_bcast_bytes (grid%gridpt_stddev_mult3d, config_flags%num_pert_3d * RWORDSIZE )
369 CALL wrf_dm_bcast_bytes (grid%lengthscale_mult3d, config_flags%num_pert_3d * RWORDSIZE )
370 CALL wrf_dm_bcast_bytes (grid%timescale_mult3d, config_flags%num_pert_3d * RWORDSIZE )
371 CALL wrf_dm_bcast_bytes (grid%stddev_cutoff_mult3d, config_flags%num_pert_3d * RWORDSIZE )
372 CALL wrf_dm_bcast_bytes (grid%ISEED_MULT3D, config_flags%num_pert_3d * IWORDSIZE )
373 CALL wrf_dm_bcast_bytes (grid%mult3d_vertstruc, config_flags%num_pert_3d * IWORDSIZE )
376 Loop_multi_perturb: DO n = 2, config_flags%num_pert_3d
377 CALL contiguize_2d ( .TRUE. , grid%SPFORCS3d, SPFORCS3d_loc, n, &
378 ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, &
379 ids, ide, jds, jde, 1, config_flags%num_pert_3d, &
380 ims, ime, jms, jme, 1, config_flags%num_pert_3d )
381 CALL contiguize_2d ( .TRUE. , grid%SPFORCC3d, SPFORCC3d_loc, n, &
382 ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, &
383 ids, ide, jds, jde, 1, config_flags%num_pert_3d, &
384 ims, ime, jms, jme, 1, config_flags%num_pert_3d )
385 CALL contiguize_2d ( .TRUE. , grid%SP_AMP3d, SP_AMP3d_loc, n, &
386 ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, &
387 ids, ide, jds, jde, 1, config_flags%num_pert_3d, &
388 ims, ime, jms, jme, 1, config_flags%num_pert_3d )
389 if ((.not.config_flags%restart) .or. (.not.config_flags%hrrr_cycling)) then
390 call rand_seed (config_flags, grid%ISEED_MULT3D(n), grid%iseedarr_mult3d(:,n) , 1, config_flags%seed_dim)
392 call SETUP_RAND_PERTURB('R', &
393 grid%mult3d_vertstruc(n),config_flags%restart, &
394 SP_AMP3d_loc,SPFORCC3d_loc,SPFORCS3d_loc, &
395 grid%ALPH_RAND3d(n), &
396 grid%VERTSTRUCC3d(:,:,:,n),grid%VERTSTRUCS3d(:,:,:,n),grid%VERTAMPT3d(:,n), &
397 grid%KMINFORCT,grid%KMAXFORCT, &
398 grid%LMINFORCT,grid%LMAXFORCT, &
399 grid%KMAXFORCTH,grid%LMAXFORCTH, &
400 grid%stepsp * grid%time_step,grid%DX,grid%DY, &
401 grid%gridpt_stddev_mult3d(n), &
402 grid%lengthscale_mult3d(n), &
403 grid%timescale_mult3d(n), &
404 grid%TOT_BACKSCAT_PSI,grid%ZTAU_PSI, &
405 grid%REXPONENT_PSI, &
406 ids, ide, jds, jde, kds, kde, &
407 ims, ime, jms, jme, kms, kme, &
408 its, ite, jts, jte, kts, kte )
410 ! if (.not.config_flags%restart) then ! spin up
412 ! CALL RAND_PERT_UPDATE(grid,'R', &
413 ! SPFORCS3d_loc,SPFORCC3d_loc,SP_AMP3d_loc, &
414 ! grid%ALPH_RAND3d(n), &
415 ! ips, ipe, jps, jpe, kps, kpe, &
416 ! ids, ide, jds, jde, kds, kde, &
417 ! ims, ime, jms, jme, kms, kme, &
419 ! imsx,imex,jmsx,jmex,kmsx,kmex, &
420 ! ipsx,ipex,jpsx,jpex,kpsx,kpex, &
421 ! imsy,imey,jmsy,jmey,kmsy,kmey, &
422 ! ipsy,ipey,jpsy,jpey,kpsy,kpey, &
423 ! grid%num_stoch_levels,grid%num_stoch_levels, &
424 ! grid%num_stoch_levels,grid%num_stoch_levels, &
425 ! config_flags%restart, grid%iseedarr_mult3d(:,n), &
426 ! config_flags%seed_dim, &
427 ! grid%DX,grid%DY,grid%mult3d_vertstruc(n), &
428 ! grid%PERT3D(:,:,:,n), &
429 ! grid%stddev_cutoff_mult3d(n), &
430 ! grid%gridpt_stddev_mult3d(n), &
431 ! grid%VERTSTRUCC3d(:,:,:,n),grid%VERTSTRUCS3d(:,:,:,n),grid%VERTAMPT3d(:,n) )
434 CALL contiguize_2d ( .FALSE., grid%SPFORCS3d, SPFORCS3d_loc, n, &
435 ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, &
436 ids, ide, jds, jde, 1, config_flags%num_pert_3d, &
437 ims, ime, jms, jme, 1, config_flags%num_pert_3d )
438 CALL contiguize_2d ( .FALSE., grid%SPFORCC3d, SPFORCC3d_loc, n, &
439 ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, &
440 ids, ide, jds, jde, 1, config_flags%num_pert_3d, &
441 ims, ime, jms, jme, 1, config_flags%num_pert_3d )
442 CALL contiguize_2d ( .FALSE., grid%SP_AMP3d, SP_AMP3d_loc, n, &
443 ips, ipe, jps, jpe, 1, config_flags%num_pert_3d, &
444 ids, ide, jds, jde, 1, config_flags%num_pert_3d, &
445 ims, ime, jms, jme, 1, config_flags%num_pert_3d )
446 END DO Loop_multi_perturb
447 ENDIF If_multi_perturb
448 IF ( wrf_dm_on_monitor() ) CLOSE (stochpert_unit)
451 ! Initialize Stochastic Parameter Perturbations to convection scheme
452 IF (grid%spp_conv==1) then
453 if (.not.config_flags%restart) then ! set random number seed (else iseedarray is read in from restart files)
454 call rand_seed (config_flags, grid%iseed_spp_conv, grid%iseedarr_spp_conv , 1, config_flags%seed_dim)
456 call SETUP_RAND_PERTURB('S', &
457 grid%vertstruc_spp_conv,config_flags%restart, &
459 grid%SPFORCC2,grid%SPFORCS2,grid%ALPH_RAND2, &
460 grid%VERTSTRUCC,grid%VERTSTRUCS,grid%VERTAMPT, &
461 grid%KMINFORCT,grid%KMAXFORCT, &
462 grid%LMINFORCT,grid%LMAXFORCT, &
463 grid%KMAXFORCTH,grid%LMAXFORCTH, &
464 grid%time_step,grid%DX,grid%DY, &
465 grid%gridpt_stddev_spp_conv, &
466 grid%lengthscale_spp_conv, &
467 grid%timescale_spp_conv, &
468 grid%TOT_BACKSCAT_PSI,grid%ZTAU_PSI, &
469 grid%REXPONENT_PSI, &
470 ids, ide, jds, jde, kds, kde, &
471 ims, ime, jms, jme, kms, kme, &
472 its, ite, jts, jte, kts, kte )
474 ! Initialize Stochastic Parameter Peturbations (SPP) to PBL scheme
475 IF (grid%spp_pbl==1) then
476 if (.not.config_flags%restart) then ! set random number seed (else iseedarray is read in from restart files)
477 call rand_seed (config_flags, grid%iseed_spp_pbl, grid%iseedarr_spp_pbl , 1, config_flags%seed_dim)
479 call SETUP_RAND_PERTURB('Q', &
480 grid%vertstruc_spp_pbl,config_flags%restart, &
482 grid%SPFORCC3,grid%SPFORCS3,grid%ALPH_RAND3, &
483 grid%VERTSTRUCC,grid%VERTSTRUCS,grid%VERTAMPT, &
484 grid%KMINFORCT,grid%KMAXFORCT, &
485 grid%LMINFORCT,grid%LMAXFORCT, &
486 grid%KMAXFORCTH,grid%LMAXFORCTH, &
487 grid%time_step,grid%DX,grid%DY, &
488 grid%gridpt_stddev_spp_pbl, &
489 grid%lengthscale_spp_pbl, &
490 grid%timescale_spp_pbl, &
491 grid%TOT_BACKSCAT_PSI,grid%ZTAU_PSI, &
492 grid%REXPONENT_PSI, &
493 ids, ide, jds, jde, kds, kde, &
494 ims, ime, jms, jme, kms, kme, &
495 its, ite, jts, jte, kts, kte )
497 ! Initialize Stochastic Parameter Peturbations (SPP) to LSM scheme
498 IF (grid%spp_lsm==1) then
499 if (.not.config_flags%restart) then ! set random number seed (else iseedarray is read in from restart files)
500 call rand_seed (config_flags, grid%iseed_spp_lsm, grid%iseedarr_spp_lsm , 1, config_flags%seed_dim)
502 call SETUP_RAND_PERTURB('O', &
503 grid%vertstruc_spp_lsm,config_flags%restart, &
505 grid%SPFORCC4,grid%SPFORCS4,grid%ALPH_RAND4, &
506 grid%VERTSTRUCC,grid%VERTSTRUCS,grid%VERTAMPT, &
507 grid%KMINFORCT,grid%KMAXFORCT, &
508 grid%LMINFORCT,grid%LMAXFORCT, &
509 grid%KMAXFORCTH,grid%LMAXFORCTH, &
510 grid%time_step,grid%DX,grid%DY, &
511 grid%gridpt_stddev_spp_lsm, &
512 grid%lengthscale_spp_lsm, &
513 grid%timescale_spp_lsm, &
514 grid%TOT_BACKSCAT_PSI,grid%ZTAU_PSI, &
515 grid%REXPONENT_PSI, &
516 ids, ide, jds, jde, kds, kde, &
517 ims, ime, jms, jme, kms, kme, &
518 its, ite, jts, jte, kts, kte )
521 ENDIF ! skebs or sppt or rand_perturb or spp
523 END SUBROUTINE INITIALIZE_STOCH
525 ! --- END SETUP STOCHASTIC PERTURBATION SCHEMES ----------
528 subroutine SETUP_RAND_PERTURB( variable_in,&
529 skebs_vertstruc,restart, &
530 SP_AMP,SPFORCC,SPFORCS,ALPH, &
531 VERTSTRUCC,VERTSTRUCS,VERTAMP, &
532 KMINFORCT,KMAXFORCTH,LMINFORCT,LMAXFORCTH, &
533 KMAXFORCT,LMAXFORCT, &
535 gridpt_stddev_rand_perturb, l_rand_perturb, &
537 TOT_BACKSCAT,ZTAU,REXPONENT, &
538 ids, ide, jds, jde, kds, kde, &
539 ims, ime, jms, jme, kms, kme, &
540 its, ite, jts, jte, kts, kte )
548 REAL, PARAMETER :: RPI= 3.141592653589793 !4.0*atan(1.0)
549 CHARACTER, INTENT(IN) :: variable_in ! W=SKEBS_PSI, T=SKEBS_T, P=SPPT, R=RAND_PERTURB
550 CHARACTER :: variable
552 ! Common to all schemes
553 INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde, &
554 ims, ime, jms, jme, kms, kme, &
555 its, ite, jts, jte, kts, kte
556 INTEGER :: IER,IK,IL,I,J,itime_step,skebs_vertstruc, &
557 KMINFORCT,LMINFORCT,KMAXFORCT,LMAXFORCT,KMAXFORCTH,LMAXFORCTH, &
558 KMAX,LMAX,LENSAV,ILEV
559 REAL :: DX,DY,RY,RX,ALPH,RHOKLMAX,ZREF,RHOKL,EPS
560 REAL, DIMENSION (ims:ime,jms:jme) :: SPFORCS,SPFORCC,SP_AMP
561 REAL, DIMENSION (ims:ime,kms:kme,jms:jme) :: VERTSTRUCC,VERTSTRUCS
562 REAL, DIMENSION (kms:kme) :: VERTAMP
563 REAL, DIMENSION (ids:ide,jds:jde) :: ZCHI
565 ! SPPT and perturb_rand specific
566 REAL :: gridpt_stddev_rand_perturb,kappat,tau_rand_perturb,l_rand_perturb
567 REAL, DIMENSION (ims:ime,jms:jme) :: var_sigma1
571 REAL :: z,phi,ZGAMMAN,ZCONSTF0,TOT_BACKSCAT,ZTAU,REXPONENT,ZSIGMA2
572 LOGICAL :: is_print = .true.
575 variable = variable_in
576 ! --------- SETUP PARAMETERS ---------------------------------------
577 KMAX=(jde-jds)+1 !NLAT
578 LMAX=(ide-ids)+1 !NLON
581 LENSAV= 4*(KMAX+LMAX)+INT(LOG(REAL(KMAX))) + INT(LOG(REAL(LMAX))) + 8
583 ! --------- ALLOCATE FIELDS FOR FFTPACK----------------------------
584 ! --------- ALLOCATE FIELDS FOR FFTPACK----------------------------
585 IF ( ALLOCATED(WSAVE1) ) DEALLOCATE(WSAVE1)
586 IF ( ALLOCATED(WSAVE2) ) DEALLOCATE(WSAVE2)
587 ALLOCATE(WSAVE1(LENSAV),WSAVE2(LENSAV))
589 IF ( ALLOCATED(WAVENUMBER_K)) DEALLOCATE(WAVENUMBER_K)
590 IF ( ALLOCATED(WAVENUMBER_L)) DEALLOCATE(WAVENUMBER_L)
591 ALLOCATE (wavenumber_k(jds:jde),wavenumber_l(ids:ide))
593 ! -------- INITIALIZE FFTPACK ROUTINES -----------------------------
594 call CFFT1I (LMAX, WSAVE1, LENSAV, IER)
595 if(ier.ne. 0) write(*,95) ier
597 call CFFT1I (KMAX, WSAVE2, LENSAV, IER)
598 if(ier.ne. 0) write(*,95) ier
600 95 format('error in cFFT2I= ',i5)
602 call findindex( wavenumber_k, wavenumber_l, &
603 ids, ide, jds, jde, kds, kde, &
604 ims, ime, jms, jme, kms, kme, &
605 its, ite, jts, jte, kts, kte )
607 ! set maximal perturbed wavenumber based on gridpoints in domain
608 KMAXFORCT=min0(((ide-ids)+1)/2,((jde-jds)+1 )/2)-5
610 if (KMAXFORCT > KMAXFORCTH) then
613 if (LMAXFORCT > LMAXFORCTH) then
618 ! --------------------------------------------------------------------------------------
619 ! ---------- INITIALIZE STOCHASTIC KINETIC-ENERGY BACKSCATTER SCHEME (SKEBS) ----------
620 ! --------------------------------------------------------------------------------------
621 ALPH = float(itime_step)/ZTAU ! approximation of 1.-exp(-itime_step/ZTAU_PSI)
622 ZSIGMA2=1./(12.0*ALPH)
625 IF (variable == 'W') then
627 WRITE(*,'('' =============================================='')')
628 WRITE(*,'('' >> Initializing STREAMFUNCTION forcing pattern of << '')')
629 WRITE(*,'('' >> stochastic kinetic-energy backscatter scheme << '')')
630 WRITE(*,'('' Total backscattered energy, TOT_BACKSCAT_PSI '',E12.5)') TOT_BACKSCAT
631 WRITE(*,'('' Exponent for energy spectra, REXPONENT_PSI ='',E12.5)') REXPONENT
632 WRITE(*,'('' Minimal wavenumber of streamfunction forcing, LMINFORC ='',I10)') LMINFORCT
633 WRITE(*,'('' Maximal wavenumber of streamfunction forcing, LMAXFORC ='',I10)') LMAXFORCT
634 WRITE(*,'('' Minimal wavenumber of streamfunction forcing, KMINFORC ='',I10)') KMINFORCT
635 WRITE(*,'('' Maximal wavenumber of streamfunction forcing, KMAXFORC ='',I10)') KMAXFORCT
636 WRITE(*,'('' skebs_vertstruc '',I10)') skebs_vertstruc
637 WRITE(*,'('' Time step: itime_step='',I10)') itime_step
638 WRITE(*,'('' Decorrelation time of noise, ZTAU_PSI ='',E12.5)') ZTAU
639 WRITE(*,'('' Variance of noise, ZSIGMA2_EPS ='',E12.5)') ZSIGMA2
640 WRITE(*,'('' Autoregressive parameter 1-ALPH_PSI ='',E12.5)') 1.-ALPH
641 WRITE(*,'('' =============================================='')')
643 ! Unit of SPSTREAM_AMP: sqrt(m^2/s^3 1/s m**2(p+1)) m**-2(p/2) = m^/s^2 * m**[(p+1)-p] = m^2/s^2 m
644 ELSEIF (variable == 'T') then
646 WRITE(*,'('' =============================================='')')
647 WRITE(*,'('' >> Initializing TEMPERATURE forcing pattern of << '')')
648 WRITE(*,'('' >> stochastic kinetic-energy backscatter scheme << '')')
649 WRITE(*,'('' Total backscattered energy, TOT_BACKSCAT_T '',E12.5)') TOT_BACKSCAT
650 WRITE(*,'('' Exponent for energy spectra, REXPONENT_T ='',E12.5)') REXPONENT
651 WRITE(*,'('' Minimal wavenumber of tempearature forcing, LMINFORC ='',I10)') LMINFORCT
652 WRITE(*,'('' Maximal wavenumber of tempearature forcing, LMAXFORC ='',I10)') LMAXFORCT
653 WRITE(*,'('' Minimal wavenumber of tempearature forcing, KMINFORC ='',I10)') KMINFORCT
654 WRITE(*,'('' Maximal wavenumber of tempearature forcing, KMAXFORC ='',I10)') KMAXFORCT
655 WRITE(*,'('' skebs_vertstruc '',I10)') skebs_vertstruc
656 WRITE(*,'('' Decorrelation time of noise, ZTAU_T ='',E12.5)') ZTAU
657 WRITE(*,'('' Variance of noise, ZSIGMA2_ETA ='',E12.5)') ZSIGMA2
658 WRITE(*,'('' Autoregressive parameter 1-ALPH_T ='',E12.5)') 1.-ALPH
659 WRITE(*,'('' =============================================='')')
662 IF ((variable == 'P') .or. (variable == 'R') .or. (variable == 'S') .or. (variable == 'Q') .or. (variable == 'O')) then
663 kappat= L_rand_perturb**2 ! L^2= kappa*T, where L is a length scale in m; set to for L=100km
664 phi = exp (-float(itime_step)/tau_rand_perturb)
668 ! --------------------------------------------------------------------------------------
669 ! ---------- INITIALIZE STOCHASTICALLY PERTURBED PHYSICAL TENDENCY SCHEME --------------
670 ! --------------------------------------------------------------------------------------
671 if (variable == 'P') then
673 WRITE(*,'('' =============================================='')')
674 WRITE(*,'('' >> Initializing Stochastically Perturbed Physics Tendency scheme << '')')
675 WRITE(*,'('' sppt_vertstruc '',I10)') skebs_vertstruc
676 WRITE(*,'('' Decorrelation time of noise, Tau ='',E12.5)') tau_rand_perturb
677 WRITE(*,'('' Autoregressive parameter Phi ='',E12.5)') phi
678 WRITE(*,'('' Length Scale L'',E12.5)') l_rand_perturb
679 WRITE(*,'('' Variance in gridpoint space'',E12.5)') gridpt_stddev_rand_perturb
680 WRITE(*,'('' =============================================='')')
683 ! --------------------------------------------------------------------------------------
684 ! -------------------- INITIALIZE RANDOM PERTUBATIONS -------------------------------
685 ! --------------------------------------------------------------------------------------
686 if (variable == 'R') then
688 WRITE(*,'('' =============================================='')')
689 WRITE(*,'('' >> Initializing random perturbations << '')')
690 WRITE(*,'('' rand_pert_vertstruc '',I10)') skebs_vertstruc
691 WRITE(*,'('' Decorrelation time of noise, Tau ='',E12.5)') tau_rand_perturb
692 WRITE(*,'('' Autoregressive parameter Phi ='',E12.5)') phi
693 WRITE(*,'('' Length Scale L'',E12.5)') l_rand_perturb
694 WRITE(*,'('' Variance in gridpoint space'',E12.5)') gridpt_stddev_rand_perturb
695 WRITE(*,'('' =============================================='')')
698 if (variable == 'S') then
700 WRITE(*,'('' =============================================='')')
701 WRITE(*,'('' >> Initializing stochastic parameter perturbations for convection<< '')')
702 WRITE(*,'('' rand_pert_vertstruc2 '',I10)') skebs_vertstruc
703 WRITE(*,'('' Decorrelation time of noise, Tau ='',E12.5)') tau_rand_perturb
704 WRITE(*,'('' Autoregressive parameter Phi ='',E12.5)') phi
705 WRITE(*,'('' Length Scale L'',E12.5)') l_rand_perturb
706 WRITE(*,'('' Variance in gridpoint space'',E12.5)') gridpt_stddev_rand_perturb
707 WRITE(*,'('' =============================================='')')
710 if (variable == 'Q') then
712 WRITE(*,'('' =============================================='')')
713 WRITE(*,'('' >> Initializing stochastic parameter perturbations for PBL<< '')')
714 WRITE(*,'('' rand_pert_vertstruc3 '',I10)') skebs_vertstruc
715 WRITE(*,'('' Decorrelation time of noise, Tau ='',E12.5)') tau_rand_perturb
716 WRITE(*,'('' Autoregressive parameter Phi ='',E12.5)') phi
717 WRITE(*,'('' Length Scale L'',E12.5)') l_rand_perturb
718 WRITE(*,'('' Variance in gridpoint space'',E12.5)') gridpt_stddev_rand_perturb
719 WRITE(*,'('' =============================================='')')
722 if (variable == 'O') then
724 WRITE(*,'('' =============================================='')')
725 WRITE(*,'('' >> Initializing stochastic parameter perturbations for LSM<< '')')
726 WRITE(*,'('' rand_pert_vertstruc4 '',I10)') skebs_vertstruc
727 WRITE(*,'('' Decorrelation time of noise, Tau ='',E12.5)') tau_rand_perturb
728 WRITE(*,'('' Autoregressive parameter Phi ='',E12.5)') phi
729 WRITE(*,'('' Length Scale L'',E12.5)') l_rand_perturb
730 WRITE(*,'('' Variance in gridpoint space'',E12.5)') gridpt_stddev_rand_perturb
731 WRITE(*,'('' =============================================='')')
735 ! --------------------------------------------------------------------------------------
736 ! Compute Normalization constants
737 ! --------------------------------------------------------------------------------------
741 ! Fill lower left quadrant of ZCHI. For this range the indeces IK,IL
742 DO IK=jds-1,jde ! These are now wavenumbers
744 if (((sqrt((IK/RY*IK/RY)+(IL/RX*IL/RX)).lt.((KMAXFORCT+0.5)/RX)).and.&
745 (sqrt((IK/RY*IK/RY)+(IL/RX*IL/RX)).ge.((KMINFORCT-0.5)/RX))) .or. &
746 ((sqrt((IK/RY*IK/RY)+(IL/RX*IL/RX)).lt.((LMAXFORCT+0.5)/RY)).and.&
747 (sqrt((IK/RY*IK/RY)+(IL/RX*IL/RX)).ge.((LMINFORCT-0.5)/RY))))then
748 if ((IK>0).or.(IL>0)) then
749 if (variable == 'W') then
750 ZCHI(IL+1,IK+1)=((IK/RY*IK/RY)+(IL/RX*IL/RX))**(REXPONENT/2.) ! SKEBS :U
751 ZGAMMAN= ZGAMMAN + ((IK/RY*IK/RY)+(IL/RX*IL/RX))**(REXPONENT+1)
752 else if (variable == 'T') then
753 ZCHI(IL+1,IK+1)=((IK/RY*IK/RY)+(IL/RX*IL/RX))**(REXPONENT/2.) ! SKEBS :T
754 ZGAMMAN= ZGAMMAN + ((IK/RY*IK/RY)+(IL/RX*IL/RX))**(REXPONENT)
755 else if ((variable == 'P') .or. (variable == 'R') .or. (variable == 'S') .or. (variable == 'O') .or. (variable == 'Q ')) then
756 ZCHI(IL+1,IK+1)=exp( -2*RPI**2*kappat*((IK/RY*IK/RY)+(IL/RX*IL/RX)) ) !SPPT
757 ZGAMMAN= ZGAMMAN + exp( -4*RPI**2*kappat*((IK/RY*IK/RY)+(IL/RX*IL/RX)) ) !SPPT
763 ZGAMMAN=4.0*ZGAMMAN !account for all quadrants, although only one is Filled
764 if (variable == 'W') then
765 ZCONSTF0=SQRT(ALPH*TOT_BACKSCAT/(float(itime_step)*ZSIGMA2*ZGAMMAN))/(2*RPI)
766 elseif (variable == 'T') then
767 ZCONSTF0=SQRT(T0*ALPH*TOT_BACKSCAT/(float(itime_step)*cp*ZSIGMA2*ZGAMMAN))
768 elseif ((variable == 'P') .or. (variable == 'R') .or. (variable == 'S') .or. (variable == 'O') .or. (variable == 'Q ')) then
769 ZCONSTF0= gridpt_stddev_rand_perturb*sqrt((1.-phi**2)/(2.*ZGAMMAN))
773 ! --------------------------------------------------------------------------------------
774 ! Now the wavenumber-dependent amplitudes
775 ! --------------------------------------------------------------------------------------
776 ! Note: There are symmetries and anti-symmetries to ensure real-valued back transforms
777 ! Fill lower left quadrant of matrix of noise amplitudes for wavenumbers K=0,KMAX/2
781 if ((IL .le. (LMAX/2+1)) .and. (IK .le. (KMAX/2+1)) ) then
782 SP_AMP(IL,IK) = ZCONSTF0*ZCHI(IL,IK)
787 ! Fill other quadrants:
788 ! Upper left quadrant
791 if ( (IL .gt. (LMAX/2+1)) .and. (IK .le. (KMAX/2+1)) ) then
792 SP_AMP(IL,IK) = ZCONSTF0*ZCHI(LMAX-IL+2,IK)
797 ! Lower right quadrant
800 if ((IK .gt. (KMAX/2+1)) .and. (IL.le.LMAX/2) ) then
801 SP_AMP(IL,IK) = ZCONSTF0*ZCHI(IL,KMAX-IK+2)
806 ! Upper right quadrant
809 if ((IK .gt. (KMAX/2+1)) .and. (IL.gt.LMAX/2) ) then
810 SP_AMP(IL,IK) = ZCONSTF0*ZCHI(LMAX-IL+2,KMAX-IK+2)
815 ! -----------------------------------------
816 ! Array for vertical structure if desired
817 VERTAMP=1.0 ! Define vertical amplitude here.
819 IF (skebs_vertstruc==1) then
822 RHOKLMAX= sqrt(KMAX**2/DY**2 + LMAX**2/DX**2)
827 if (IL.le.(LMAX/2)) then
828 RHOKL = sqrt((IK+1)**2/DY**2 + (IL+1)**2/DX**2)
829 EPS = ((RHOKLMAX - RHOKL)/ RHOKLMAX) * (ILEV/ZREF) * RPI
830 VERTSTRUCC(IL,ILEV,IK) = cos ( eps* (IL+1) )
831 VERTSTRUCS(IL,ILEV,IK) = sin ( eps* (IL+1) )
833 RHOKL = sqrt((IK+1)**2/DY**2 + (LMAX-IL+2)**2/DX**2)
834 EPS = ((RHOKLMAX - RHOKL)/ RHOKLMAX) * (ILEV/ZREF) * RPI
835 VERTSTRUCC (IL,ILEV,IK) = cos ( eps* (LMAX-IL+2) )
836 VERTSTRUCS (IL,ILEV,IK) = - sin ( eps* (LMAX-IL+2) )
843 END subroutine SETUP_RAND_PERTURB
845 ! ------------------------------------------------------------------
846 !************** UPDATE STOCHASTIC PATTERN IN WAVENUMBER SPACE**********
847 ! ------------------------------------------------------------------
849 subroutine UPDATE_STOCH( &
850 SPFORCS,SPFORCC,SP_AMP,ALPH, &
851 restart,iseedarr,seed_dim, &
852 ids, ide, jds, jde, kds, kde, &
853 ims, ime, jms, jme, kms, kme, &
854 its, ite, jts, jte, kts, kte )
857 REAL, DIMENSION( ids:ide,jds:jde) :: ZRANDNOSS,ZRANDNOSC
858 REAL, DIMENSION (ims:ime,jms:jme) :: SPFORCS,SPFORCC,SP_AMP
859 INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde, &
860 ims, ime, jms, jme, kms, kme, &
861 its, ite, jts, jte, kts, kte
862 INTEGER , INTENT(IN) :: seed_dim
864 INTEGER, DIMENSION (seed_dim) , INTENT(INOUT) :: iseedarr
865 INTEGER , ALLOCATABLE , DIMENSION(:) :: iseed
867 REAL, PARAMETER :: thresh = 3.0
868 INTEGER ::IL, IK,LMAX,KMAX
870 LOGICAL :: LGAUSS,RESTART
872 KMAX=(jde-jds)+1 !NLAT
873 LMAX=(ide-ids)+1 !NATX
875 CALL random_seed(size=how_many)
876 IF ( ALLOCATED(iseed)) DEALLOCATE(iseed)
877 ALLOCATE(iseed(how_many))
878 iseed=iseedarr(1:how_many)
879 call random_seed(put=iseed(1:how_many))
881 ! Pick the distribution of the noise
882 ! Random noise uses global indexes to ensure necessary symmetries and anti-symmetries
883 ! of random forcing when run on multiple processors
890 if (abs(z)<thresh) exit
895 if (abs(z)<thresh) exit
903 CALL RANDOM_NUMBER(z)
904 ZRANDNOSS(IL,IK)=z-0.5
905 CALL RANDOM_NUMBER(z)
906 ZRANDNOSC(IL,IK)=z-0.5
911 ! Note: There are symmetries and anti-symmetries to ensure real-valued back transforms
912 ! for symmetric part: left and right half axis symmetric
915 if ((IK.le.(KMAX/2+1)) .and. (IK>1)) then ! Upper half
917 SPFORCC(IL,IK) = (1.-ALPH)*SPFORCC(IL,IK) + SP_AMP(IL,IK) * ZRANDNOSC(IL,IK)
918 SPFORCS(IL,IK) = (1.-ALPH)*SPFORCS(IL,IK) + SP_AMP(IL,IK) * ZRANDNOSS(IL,IK)
922 if ((IL.le.(LMAX/2+1))) then
923 SPFORCC(IL,IK) = (1.-ALPH)*SPFORCC(IL,IK) + SP_AMP(IL,IK) * ZRANDNOSC(IL,IK)
924 SPFORCS(IL,IK) = (1.-ALPH)*SPFORCS(IL,IK) + SP_AMP(IL,IK) * ZRANDNOSS(IL,IK)
925 elseif ((IL.gt.(LMAX/2+1))) then
926 SPFORCC(IL,IK) = (1.-ALPH)*SPFORCC(IL,IK) + SP_AMP(IL,IK) * ZRANDNOSC(LMAX-IL+2,IK)
927 SPFORCS(IL,IK) = (1.-ALPH)*SPFORCS(IL,IK) - SP_AMP(IL,IK) * ZRANDNOSS(LMAX-IL+2,IK)
934 if (IK.gt.(KMAX/2+1)) then ! Lower half
936 if (IL.le.(LMAX/2+1).and.(IL.gt.1)) then !lower left
937 SPFORCC(IL,IK) = (1.-ALPH)* SPFORCC(IL,IK) + SP_AMP(IL,IK) * ZRANDNOSC(LMAX-IL+2,KMAX-IK+2)
938 SPFORCS(IL,IK) = (1.-ALPH)* SPFORCS(IL,IK) - SP_AMP(IL,IK) * ZRANDNOSS(LMAX-IL+2,KMAX-IK+2)
939 elseif (IL.eq.1) then !don't exceed index
940 SPFORCC(IL,IK) = (1.-ALPH)* SPFORCC(IL,IK) + SP_AMP(IL,IK) * ZRANDNOSC( 1,KMAX-IK+2)
941 SPFORCS(IL,IK) = (1.-ALPH)* SPFORCS(IL,IK) - SP_AMP(IL,IK) * ZRANDNOSS( 1,KMAX-IK+2)
942 elseif (IL.gt.(LMAX/2+1)) then !lower right
943 SPFORCC(IL,IK) = (1.-ALPH)* SPFORCC(IL,IK) + SP_AMP(IL,IK) * ZRANDNOSC(LMAX-IL+2,KMAX-IK+2)
944 SPFORCS(IL,IK) = (1.-ALPH)* SPFORCS(IL,IK) - SP_AMP(IL,IK) * ZRANDNOSS(LMAX-IL+2,KMAX-IK+2)
950 call random_seed(get=iseed(1:how_many))
952 iseedarr(1:how_many)=iseed
954 END subroutine UPDATE_STOCH
955 ! ------------------------------------------------------------------
956 SUBROUTINE UPDATE_STOCH_TEN(ru_tendf,rv_tendf,t_tendf, &
957 ru_tendf_stoch,rv_tendf_stoch,rt_tendf_stoch,&
959 ids, ide, jds, jde, kds, kde, &
960 ims, ime, jms, jme, kms, kme, &
961 its, ite, jts, jte, kts, kte, &
962 kte_stoch,kme_stoch )
965 INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde, &
966 ims, ime, jms, jme, kms, kme, &
967 its, ite, jts, jte, kts, kte, &
970 REAL , DIMENSION(ims:ime , kms:kme, jms:jme),INTENT(INOUT) :: &
971 ru_tendf, rv_tendf, t_tendf
973 REAL , DIMENSION(ims:ime , kms:kme_stoch, jms:jme) :: &
974 ru_tendf_stoch,rv_tendf_stoch,rt_tendf_stoch
976 REAL , DIMENSION(ims:ime,jms:jme) , INTENT(IN) :: mu,mub
977 REAL , DIMENSION(kms:kme) , INTENT(IN) :: c1h,c2h
983 DO j = jts,MIN(jde-1,jte)
987 ru_tendf(i,k,j) = ru_tendf(i,k,j) + ru_tendf_stoch(i,kh,j) * ((c1h(k)*mu(i,j))+(c1h(k)*mub(i,j)+c2h(k)))
995 DO i = its,MIN(ide-1,ite)
996 rv_tendf(i,k,j) = rv_tendf(i,k,j) + rv_tendf_stoch(i,kh,j) * ((c1h(k)*mu(i,j))+(c1h(k)*mub(i,j)+c2h(k)))
1001 DO j = jts,MIN(jde-1,jte)
1004 DO i = its,MIN(ide-1,ite)
1005 t_tendf(i,k,j) = t_tendf(i,k,j) + rt_tendf_stoch(i,kh,j) * ((c1h(k)*mu(i,j))+(c1h(k)*mub(i,j)+c2h(k)))
1010 END SUBROUTINE UPDATE_STOCH_TEN
1011 ! ------------------------------------------------------------------
1012 !!************** PERTURB PHYSICS TENDENCIES (except T) FOR SPPT *******************
1013 ! ------------------------------------------------------------------
1014 subroutine perturb_physics_tend(gridpt_stddev_sppt, &
1015 sppt_thresh_fact,rstoch, &
1016 ru_tendf,rv_tendf,t_tendf,moist_tend, &
1017 ids, ide, jds, jde, kds, kde, &
1018 ims, ime, jms, jme, kms, kme, &
1019 its, ite, jts, jte, kts, kte, &
1020 kte_stoch,kme_stoch )
1022 ! This subroutine add stochastic perturbations of the form
1024 ! rx_tendf(i,k,j) = rx_tendf(i,k,j)*(1.0 + rstoch(i,k,j))
1026 ! to the tendencies of U, V, and Q.
1027 ! Since the temperature perturbations do not include the micro-physics
1028 ! tendencies at this point, the stochastic tendency perturbations to
1029 ! temperature are added in subroutine rk_addtend_dry of module module_em.F
1032 INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde, &
1033 ims, ime, jms, jme, kms, kme, &
1034 its, ite, jts, jte, kts, kte, &
1037 REAL , DIMENSION(ims:ime , kms:kme, jms:jme),INTENT(INOUT) :: &
1038 ru_tendf, rv_tendf, t_tendf,moist_tend
1039 REAL , DIMENSION(ims:ime,kms:kme_stoch, jms:jme),INTENT(INOUT) :: rstoch
1040 REAL :: gridpt_stddev_sppt ,thresh,sppt_thresh_fact
1044 ! Here the random process at each gridpoint is capped if it exceeds a value thresh
1046 thresh=sppt_thresh_fact*gridpt_stddev_sppt
1048 DO k = kts,min(kte-1,kte_stoch-1)
1050 ! rstoch(i,k,j)=MAX(MIN(rstoch(i,k,j),thresh),-1.*thresh))
1051 if (rstoch(i,k,j).lt.-thresh) then
1052 rstoch(i,k,j)=-thresh
1054 if (rstoch(i,k,j).gt.thresh) then
1055 rstoch(i,k,j)=thresh
1061 ! Perturb the tendencies of u,v,q,t.
1062 DO j = jts,MIN(jde-1,jte)
1064 kh = min( k, kte_stoch-1 )
1066 ru_tendf(i,k,j) = ru_tendf(i,k,j)*(1.0 + rstoch(i,kh,j))
1073 kh = min( k, kte_stoch-1 )
1074 DO i = its,MIN(ide-1,ite)
1075 rv_tendf(i,k,j) = rv_tendf(i,k,j)*(1.0 + rstoch(i,kh,j))
1080 DO j = jts,MIN(jde-1,jte)
1082 kh = min( k, kte_stoch-1 )
1083 DO i = its,MIN(ide-1,ite)
1084 moist_tend(i,k,j) = moist_tend(i,k,j)*(1.0 + rstoch(i,kh,j))
1085 t_tendf (i,k,j) = t_tendf(i,k,j)*(1.0 + rstoch(i,kh,j))
1090 end subroutine perturb_physics_tend
1092 ! ------------------------------------------------------------------
1093 !!************** UPDATE SPECTRAL PATTERN AND TRANFORM GRIDPOINT SPACE***
1094 ! ------------------------------------------------------------------
1095 ! This subroutine evolves the spectral pattern and transforms it back to gridpoint space.
1099 SUBROUTINE RAND_PERT_UPDATE (grid, variable_in, &
1100 SPFORCS,SPFORCC,SP_AMP,ALPH_RAND, &
1101 ips, ipe, jps, jpe, kps, kpe, &
1102 ids, ide, jds, jde, kds, kde, &
1103 ims, ime, jms, jme, kms, kme, &
1105 imsx,imex,jmsx,jmex,kmsx,kmex, &
1106 ipsx,ipex,jpsx,jpex,kpsx,kpex, &
1107 imsy,imey,jmsy,jmey,kmsy,kmey, &
1108 ipsy,ipey,jpsy,jpey,kpsy,kpey, &
1109 kpe_stoch,kde_stoch,kme_stoch,kte_stoch, &
1110 restart,iseedarr,seed_dim, &
1111 DX,DY,skebs_vertstruc, &
1112 RAND_PERT,thresh_fact,gridpt_stddev, &
1113 VERTSTRUCC,VERTSTRUCS,VERTAMP )
1117 USE module_domain, ONLY : domain
1118 !pajm Do we need the following line USE module_state_description, ONLY : num_pert3d
1120 USE module_dm, ONLY : local_communicator, mytask, ntasks, ntasks_x, ntasks_y, local_communicator_periodic, &
1121 wrf_dm_maxval, wrf_err_message, local_communicator_x, local_communicator_y, data_order_xzy
1127 TYPE ( domain ), INTENT(INOUT) :: grid
1130 INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde, &
1131 ims, ime, jms, jme, kms, kme, &
1132 ips, ipe, jps, jpe, kps, kpe, &
1134 INTEGER , INTENT(IN) :: imsx,imex,jmsx,jmex,kmsx,kmex, &
1135 ipsx,ipex,jpsx,jpex,kpsx,kpex, &
1136 imsy,imey,jmsy,jmey,kmsy,kmey, &
1137 ipsy,ipey,jpsy,jpey,kpsy,kpey
1138 INTEGER , INTENT(IN) :: seed_dim
1139 INTEGER :: kpe_stoch,kde_stoch,kme_stoch,kte_stoch
1141 REAL , INTENT(IN) :: ALPH_RAND,dx,dy,thresh_fact,gridpt_stddev
1142 INTEGER , INTENT(IN) :: skebs_vertstruc
1143 CHARACTER, INTENT(IN) :: variable_in ! T, U, V
1144 ! T ! random field, T
1145 ! U ! first derivative of streamfunction with regard to y; for skebs: U
1146 ! V ! first derivative of streamfunction with regard to x; for skebs: V
1148 INTEGER, DIMENSION (seed_dim), INTENT(INOUT) :: iseedarr
1149 REAL, DIMENSION(ims:ime,kms:kme, jms:jme),INTENT(IN) :: VERTSTRUCC,VERTSTRUCS
1150 REAL, DIMENSION(ims:ime,jms:jme) ,INTENT(INOUT) :: SPFORCS,SPFORCC,SP_AMP
1151 REAL, DIMENSION(kms:kme ) ,INTENT(IN) :: VERTAMP
1152 REAL, DIMENSION(ims:ime,kms:kme_stoch, jms:jme) :: RAND_PERT
1157 INTEGER :: IK,IL,ILEV,NLON,NLAT,IJ,I,J,K
1158 INTEGER :: gridsp32y,gridsm32y,gridsp32x,gridsm32x,gridsp32 ,gridsm32
1159 INTEGER :: gridep32y,gridem32y,gridep32x,gridem32x,gridep32 ,gridem32
1162 REAL, DIMENSION(ims:ime,kms:kme_stoch, jms:jme) :: RAND_REAL, RAND_IMAG
1164 CHARACTER :: variable
1166 variable = variable_in
1168 NLAT=(jde-jds)+1 !KMAX
1169 NLON=(ide-ids)+1 !LMAX
1173 ! Update the pattern generator by evolving each spectral coefficients as AR1
1176 !$OMP PRIVATE ( ij )
1177 DO ij = 1 , grid%num_tiles
1178 IF (variable .ne. 'V') THEN !T, random field, U, don't update for V
1179 CALL UPDATE_STOCH( &
1180 SPFORCS,SPFORCC,SP_AMP,ALPH_RAND, &
1181 restart,iseedarr,seed_dim, &
1182 ids, ide, jds, jde, kds, kde, &
1183 ims, ime, jms, jme, kms, kme, &
1184 grid%i_start(ij), grid%i_end(ij), grid%j_start(ij), grid%j_end(ij), kts, kte )
1187 ! Put spectral coefficients in arrays RAND_REAL,RAND_IMAG
1189 IF (variable == 'T') THEN ! T, rand
1190 DO IK=grid%j_start(ij), grid%j_end(ij)
1191 DO ILEV=kts,kte_stoch
1192 DO IL=grid%i_start(ij),grid%i_end(ij)
1193 grid%RAND_REAL(IL,ILEV,IK) = SPFORCC(IL,IK)
1194 grid%RAND_IMAG(IL,ILEV,IK) = SPFORCS(IL,IK)
1199 ELSEIF (variable == 'U') THEN !U
1200 DO IK=grid%j_start(ij), grid%j_end(ij)
1201 DO ILEV=kts,kte_stoch
1202 DO IL=grid%i_start(ij),grid%i_end(ij)
1203 grid%RAND_REAL(IL,ILEV,IK) = 2*RPI/RY* wavenumber_k(IK) * SPFORCS(IL,IK)
1204 grid%RAND_IMAG(IL,ILEV,IK) = -2*RPI/RY* wavenumber_k(IK) * SPFORCC(IL,IK)
1209 ELSEIF (variable == 'V') THEN !V
1210 DO IK=grid%j_start(ij), grid%j_end(ij)
1211 DO ILEV=kts,kte_stoch
1212 DO IL=grid%i_start(ij),grid%i_end(ij)
1213 grid%RAND_REAL(IL,ILEV,IK) = -2*RPI/RX* wavenumber_l(IL) * SPFORCS(IL,IK)
1214 grid%RAND_IMAG(IL,ILEV,IK) = 2*RPI/RX* wavenumber_l(IL) * SPFORCC(IL,IK)
1221 ! Apply vertical structure function
1223 IF (skebs_vertstruc.ne.0) then
1224 DO ILEV=kts,kte_stoch
1225 DO IL=grid%i_start(ij),grid%i_end(ij)
1226 DO IK=grid%j_start(ij), grid%j_end(ij)
1227 grid%RAND_REAL(IL,ILEV,IK) = VERTAMP(ILEV) * &
1228 (grid%RAND_REAL(IL,ILEV,IK) * VERTSTRUCC(IL,ILEV,IK) - grid%RAND_IMAG(IL,ILEV,IK) * VERTSTRUCS(IL,ILEV,IK))
1229 grid%RAND_IMAG(IL,ILEV,IK) = VERTAMP(ILEV) * &
1230 (grid%RAND_REAL(IL,ILEV,IK) * VERTSTRUCS(IL,ILEV,IK) + grid%RAND_IMAG(IL,ILEV,IK) * VERTSTRUCC(IL,ILEV,IK))
1236 !$OMP END PARALLEL DO
1238 ! Transform spectral pattern to gridpoint space
1240 #if ( defined( DM_PARALLEL ) && ( ! defined( STUBMPI ) ) )
1242 ! Roll out into latitude bands and perform FFT along latitude bands
1244 ! Save a copy of the indices as we might need them to change when
1245 ! doing the "thin" 3d arrays (where the "k" dimension is unity).
1246 ! These are the original Z-transposed and X-transposed k-dimensions.
1248 gridsp32x=grid%sp32x
1249 gridsm32x=grid%sm32x
1250 gridep32x=grid%ep32x
1251 gridem32x=grid%em32x
1257 ! Set number of vertical levels to which ever is smaller: the full number
1258 ! of vertical levels, or the number of levels to be transformed into
1261 grid%sp32x=min(kpsx,grid%num_stoch_levels)
1262 grid%sm32x=min(kmsx,grid%num_stoch_levels)
1263 grid%ep32x=min(kpex,grid%num_stoch_levels)
1264 grid%em32x=min(kmex,grid%num_stoch_levels)
1265 grid%sp32 =min(kps ,grid%num_stoch_levels)
1266 grid%sm32 =min(kms ,grid%num_stoch_levels)
1267 grid%ep32 =min(kpe ,grid%num_stoch_levels)
1268 grid%em32 =min(kme ,grid%num_stoch_levels)
1270 #include "XPOSE_RAND_REAL_z2x.inc"
1271 #include "XPOSE_RAND_IMAG_z2x.inc"
1272 call do_fftback_along_x(grid%RAND_REAL_xxx,grid%RAND_IMAG_xxx, &
1274 imsx,imex,jmsx,jmex,kmsx,min(kmex,grid%num_stoch_levels), &
1275 ipsx,ipex,jpsx,jpex,kpsx,min(kpex,grid%num_stoch_levels))
1276 #include "XPOSE_RAND_REAL_x2z.inc"
1277 #include "XPOSE_RAND_IMAG_x2z.inc"
1279 ! Roll out into longitude bands and perform FFT along longitude bands
1281 ! Save a copy of the indices as we might need them to change when
1282 ! doing the "thin" 3d arrays (where the "k" dimension is unity).
1283 ! These are the original Y-transposed k-dimensions.
1285 gridsp32y=grid%sp32y
1286 gridsm32y=grid%sm32y
1287 gridep32y=grid%ep32y
1288 gridem32y=grid%em32y
1290 ! Again, set number of vertical levels to the min of the number of levels and the
1291 ! number of stochastic levels.
1293 grid%sp32y=min(kpsy,grid%num_stoch_levels)
1294 grid%sm32y=min(kmsy,grid%num_stoch_levels)
1295 grid%ep32y=min(kpey,grid%num_stoch_levels)
1296 grid%em32y=min(kmey,grid%num_stoch_levels)
1298 #include "XPOSE_RAND_REAL_z2y.inc"
1299 #include "XPOSE_RAND_IMAG_z2y.inc"
1300 call do_fftback_along_y(grid%RAND_REAL_yyy,grid%RAND_IMAG_yyy, &
1302 imsy,imey,jmsy,jmey,kmsy,min(kmey,grid%num_stoch_levels), &
1303 ipsy,ipey,jpsy,jpey,kpsy,min(kpey,grid%num_stoch_levels))
1304 #include "XPOSE_RAND_REAL_y2z.inc"
1305 #include "XPOSE_RAND_IMAG_y2z.inc"
1307 ! Put the original vertical "k" dimensions back.
1309 grid%sp32x=gridsp32x
1310 grid%sm32x=gridsm32x
1311 grid%ep32x=gridep32x
1312 grid%em32x=gridem32x
1313 grid%sp32y=gridsp32y
1314 grid%sm32y=gridsm32y
1315 grid%ep32y=gridep32y
1316 grid%em32y=gridem32y
1323 call do_fftback_along_x(grid%RAND_REAL,grid%RAND_IMAG, &
1325 ims,ime,jms,jme,kms,min(kme,grid%num_stoch_levels), &
1326 ips,ipe,jps,jpe,kps,min(kpe,grid%num_stoch_levels))
1327 call do_fftback_along_y(grid%RAND_REAL,grid%RAND_IMAG, &
1329 ims,ime,jms,jme,kms,min(kme,grid%num_stoch_levels), &
1330 ips,ipe,jps,jpe,kps,min(kpe,grid%num_stoch_levels))
1334 thresh=thresh_fact*gridpt_stddev
1336 !$OMP PRIVATE ( ij )
1337 DO ij = 1 , grid%num_tiles
1338 DO k=kts,min(kte,grid%num_stoch_levels)
1339 DO I=grid%i_start(ij), grid%i_end(ij)
1340 DO j=grid%j_start(ij), grid%j_end(ij)
1341 RAND_PERT(I,K,J)=grid%RAND_REAL(I,K,J)
1342 RAND_PERT(I,K,J)=MAX(MIN(grid%RAND_REAL(I,K,J),thresh),-1.0*thresh)
1347 !$OMP END PARALLEL DO
1350 END SUBROUTINE RAND_PERT_UPDATE
1352 ! ------------------------------------------------------------------
1353 !!************** SUBROUTINE DO_FFTBACK_ALONG_X
1354 ! ------------------------------------------------------------------
1355 subroutine do_fftback_along_x( &
1358 imsx,imex,jmsx,jmex,kmsx,kmex, &
1359 ipsx,ipex,jpsx,jpex,kpsx,kpex )
1362 INTEGER, INTENT(IN):: imsx,imex,jmsx,jmex,kmsx,kmex, &
1363 ipsx,ipex,jpsx,jpex,kpsx,kpex, &
1367 REAL, DIMENSION (imsx:imex, kmsx:kmex, jmsx:jmex) :: fieldc,fields
1369 COMPLEX, DIMENSION (ipsx:ipex) :: dummy_complex
1370 INTEGER :: IER,LENWRK,KMAX,LMAX,I,J,K
1371 REAL, ALLOCATABLE :: WORK(:)
1373 CHARACTER (LEN=160) :: mess
1380 ALLOCATE(WORK(LENWRK))
1381 LENSAV= 4*(KMAX+LMAX)+INT(LOG(REAL(KMAX))) + INT(LOG(REAL(LMAX))) + 8
1386 dummy_complex(i)=cmplx(fieldc(i,k,j),fields(i,k,j))
1388 CALL cFFT1B (LMAX, 1 ,dummy_complex,LMAX, WSAVE1, LENSAV, WORK, LENWRK, IER)
1390 WRITE(mess,FMT='(A)') 'error in cFFT1B in do_fftback_along_x, field U'
1391 CALL wrf_debug(0,mess)
1394 fieldc(i,k,j)=real(dummy_complex(i))
1395 fields(i,k,j)=imag(dummy_complex(i))
1401 end subroutine do_fftback_along_x
1403 !! ------------------------------------------------------------------
1404 !!!************** SUBROUTINE DO_FFTBACK_ALONG_Y
1405 !! ------------------------------------------------------------------
1406 subroutine do_fftback_along_y( &
1409 imsy,imey,jmsy,jmey,kmsy,kmey, &
1410 ipsy,ipey,jpsy,jpey,kpsy,kpey )
1413 INTEGER :: IER,LENWRK,KMAX,LMAX,I,J,K,skebs_vertstruc
1415 INTEGER, INTENT(IN) :: imsy,imey,jmsy,jmey,kmsy,kmey, &
1416 ipsy,ipey,jpsy,jpey,kpsy,kpey, &
1419 REAL, DIMENSION (imsy:imey, kmsy:kmey, jmsy:jmey) :: fieldc,fields
1421 COMPLEX, DIMENSION (jpsy:jpey) :: dummy_complex
1422 REAL, ALLOCATABLE :: WORK(:)
1424 CHARACTER (LEN=160) :: mess
1429 ALLOCATE(WORK(LENWRK))
1430 LENSAV= 4*(KMAX+LMAX)+INT(LOG(REAL(KMAX))) + INT(LOG(REAL(LMAX))) + 8
1437 dummy_complex(j)=cmplx(fieldc(i,k,j),fields(i,k,j))
1439 CALL cFFT1B (KMAX, 1 ,dummy_complex,KMAX, WSAVE2, LENSAV, WORK, LENWRK, IER)
1441 WRITE(mess,FMT='(A)') 'error in cFFT1B in do_fftback_along_y, field U'
1442 CALL wrf_debug(0,mess)
1445 fieldc(i,k,j)=real(dummy_complex(j))
1446 fields(i,k,j)=imag(dummy_complex(j))
1449 END DO ! k_start-k_end
1453 end subroutine do_fftback_along_y
1454 ! ------------------------------------------------------------------
1455 !!************** TRANSFORM FROM GRIDPOILT SPACE TO SPHERICAL HARMONICS **
1456 ! ------------------------------------------------------------------
1457 subroutine findindex( wavenumber_k, wavenumber_L, &
1458 ids, ide, jds, jde, kds, kde, &
1459 ims, ime, jms, jme, kms, kme, &
1460 its, ite, jts, jte, kts, kte )
1463 INTEGER :: IK,IL,KMAX,LMAX
1464 INTEGER, DIMENSION (jds:jde):: wavenumber_k
1465 INTEGER, DIMENSION (ids:ide):: wavenumber_l
1466 INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde, &
1467 ims, ime, jms, jme, kms, kme, &
1468 its, ite, jts, jte, kts, kte
1472 !map wave numbers K,L to indeces IK, IL
1474 wavenumber_k(IK)=IK-1
1476 DO IK=KMAX,KMAX/2+2,-1
1477 wavenumber_k(IK)=IK-KMAX-1
1480 wavenumber_l(IL)=IL-1
1482 DO IL=LMAX,LMAX/2+2,-1
1483 wavenumber_l(IL)=IL-LMAX-1
1486 END subroutine findindex
1488 ! ------------------------------------------------------------------
1489 subroutine gauss_noise(z)
1491 real :: x,y,r, coeff ! INPUT
1493 ! [2.1] Get two uniform variate random numbers IL range 0 to 1:
1497 call random_number( x )
1498 call random_number( y )
1500 ! [2.2] Transform to range -1 to 1 and calculate sum of squares:
1506 if ( r > 0.0 .and. r < 1.0 ) exit
1510 ! [2.3] Use Box-Muller transformation to get normal deviates:
1512 coeff = sqrt( -2.0 * log(r) / r )
1515 end subroutine gauss_noise
1516 ! ------------------------------------------------------------------
1517 SUBROUTINE rand_seed (config_flags, iseed1, iseedarr, seed_start, seed_dim )
1518 USE module_configure
1521 ! Structure that contains run-time configuration (namelist) data for domain
1522 TYPE (grid_config_rec_type) :: config_flags
1525 INTEGER :: seed_start, seed_dim, iseed1
1526 INTEGER, DIMENSION (seed_start:seed_dim), INTENT(OUT) :: iseedarr
1529 integer*8 :: fctime, one_big
1532 fctime = config_flags%start_year * ( config_flags%start_month*100+config_flags%start_day) + config_flags%start_hour
1536 if ( seed_dim-3 .lt. seed_start ) then
1537 do i = seed_start,seed_dim
1538 iseedarr(i )= iseed1+config_flags%nens*1000000
1541 do i = seed_start,seed_dim-3,4
1542 iseedarr(i )= iseed1+config_flags%nens*1000000
1543 iseedarr(i+1)= mod(fctime+iseed1*config_flags%nens*1000000,19211*one_big)
1544 iseedarr(i+2)= mod(fctime+iseed1*config_flags%nens*1000000,71209*one_big)
1545 iseedarr(i+3)= mod(fctime+iseed1*config_flags%nens*1000000,11279*one_big)
1549 end SUBROUTINE rand_seed
1551 ! ------------------------------------------------------------------
1553 SUBROUTINE contiguize_2d ( in_out, d3, d2, n , &
1554 ips, ipe, jps, jpe, kps, kpe, &
1555 ids, ide, jds, jde, kds, kde, &
1556 ims, ime, jms, jme, kms, kme )
1559 LOGICAL, INTENT(IN) :: in_out ! d3->d2 = T; d2->d3 = F
1560 INTEGER, INTENT(IN) :: n
1561 INTEGER, INTENT(IN) :: ids, ide, jds, jde, kds, kde, &
1562 ims, ime, jms, jme, kms, kme, &
1563 ips, ipe, jps, jpe, kps, kpe
1565 REAL, INTENT(INOUT), DIMENSION(ims:ime, jms:jme) :: d2
1566 REAL, INTENT(INOUT), DIMENSION(ims:ime,kms:kme,jms:jme) :: d3
1584 END SUBROUTINE contiguize_2d
1586 ! ------------------------------------------------------------------
1587 end module module_stoch