1 subroutine da_setup_be_nmm_regional(xb, be)
3 !---------------------------------------------------------------------------
4 ! Purpose: Define and allocate components of background errors
5 !---------------------------------------------------------------------------
9 type (xb_type), intent(in) :: xb ! First guess structure.
10 type (be_type), intent(out) :: be ! Back. errors structure.
12 integer :: i, j, k, m ! Loop counters.
13 integer, allocatable:: bin(:,:,:) ! Bin assigned to each 3D point
14 integer, allocatable:: bin2d(:,:) ! Bin assigned to each 2D point
15 integer :: bin_type ! Type of bin to average over.
16 integer :: num_bins ! Number of bins (3D fields).
17 integer :: num_bins2d ! Number of bins (3D fields).
18 real :: lat_min, lat_max, binwidth_lat ! Used if bin_type = 2 (degrees)..
19 real :: hgt_min, hgt_max, binwidth_hgt ! Used if bin_type = 2 (m). .
21 real, allocatable :: be1_eval_loc(:,:) ! Temp arrays.
22 real, allocatable :: be2_eval_loc(:,:) ! Temp arrays.
23 real, allocatable :: be3_eval_loc(:,:) ! Temp arrays.
24 real, allocatable :: be4_eval_loc(:,:) ! Temp arrays.
25 real, allocatable :: be5_eval_loc(:,:) ! Temp arrays.
27 real, allocatable :: be1_eval_glo(:) ! Global Eigenvalues.
28 real, allocatable :: be2_eval_glo(:) ! Global Eigenvalues.
29 real, allocatable :: be3_eval_glo(:) ! Global Eigenvalues.
30 real, allocatable :: be4_eval_glo(:) ! Global Eigenvalues.
31 real, allocatable :: be5_eval_glo(:) ! Global Eigenvalues.
33 real, allocatable :: be1_evec_loc(:,:,:) ! Local Eigenvectors.
34 real, allocatable :: be2_evec_loc(:,:,:) ! Local Eigenvectors.
35 real, allocatable :: be3_evec_loc(:,:,:) ! Local Eigenvectors.
36 real, allocatable :: be4_evec_loc(:,:,:) ! Local Eigenvectors.
37 real, allocatable :: be5_evec_loc(:,:,:) ! Local Eigenvectors.
39 real, allocatable :: be1_evec_glo(:,:) ! Global Eigenvectors.
40 real, allocatable :: be2_evec_glo(:,:) ! Global Eigenvectors.
41 real, allocatable :: be3_evec_glo(:,:) ! Global Eigenvectors.
42 real, allocatable :: be4_evec_glo(:,:) ! Global Eigenvectors.
43 real, allocatable :: be5_evec_glo(:,:) ! Global Eigenvectors.
45 real, allocatable :: be1_rf_lengthscale(:) ! RF lengthscale.
46 real, allocatable :: be2_rf_lengthscale(:) ! RF lengthscale.
47 real, allocatable :: be3_rf_lengthscale(:) ! RF lengthscale.
48 real, allocatable :: be4_rf_lengthscale(:) ! RF lengthscale.
49 real, allocatable :: be5_rf_lengthscale(:)
50 real, allocatable :: alpha_rf_lengthscale(:)
52 real, allocatable :: evec_loc(:,:,:) ! Latitudinally varying eigenvectors.
53 real, allocatable :: eval_loc(:,:) ! Latitudinally varying eigenvalues.
55 character*10 :: variable
56 integer :: ni, nj, nk, nk_2d, b
58 real, allocatable :: regcoeff1(:)
59 real, allocatable :: regcoeff2(:,:)
60 real, allocatable :: regcoeff3(:,:,:)
64 if (trace_use) call da_trace_entry("da_setup_be_nmm_regional")
66 be % v1 % name = 'psi ' ! Streamfunction
67 be % v2 % name = 'chi_u' ! Uncorrelated velocity potential.
68 be % v3 % name = 't_u' ! Unbalanced temperature.
69 be % v4 % name = 'q/qsg'
70 be % v5 % name = 'psfc' ! surface pressure
72 if(use_radarobs .and. use_radar_rf) then
73 be % v4 % name = 'qt '
77 write (unit=message(2),fmt='(3x,A,7A)') 'WRF-Var dry control variables are:', &
78 trim(be % v1 % name), ', ', trim(be % v2 % name), ', ', &
79 trim(be % v3 % name), ' and ', trim(be % v5 % name)
81 write (unit=message(3),fmt='(3x,A,A)') &
82 'Humidity control variable is ', trim(be % v4 % name)
84 write (unit=message(3),fmt='(3x,A,A)') &
85 'Humidity control variable is ', trim(be % v4 % name)
90 call da_get_unit(be_unit)
91 open(unit=be_unit,file="be.dat", status="old",form="unformatted")
94 read (be_unit) ni, nj, nk
96 allocate (bin(1:ni,1:nj,1:nk))
97 allocate (bin2d(1:ni,1:nj))
99 read (be_unit)bin_type
100 read (be_unit)lat_min, lat_max, binwidth_lat
101 read (be_unit)hgt_min, hgt_max, binwidth_hgt
102 read (be_unit)num_bins, num_bins2d
103 read (be_unit)bin(1:ni,1:nj,1:nk)
104 read (be_unit)bin2d(1:ni,1:nj)
106 ! 1.1 Read in regression coefficients
109 allocate (regcoeff1(1:num_bins))
110 allocate (regcoeff2(1:nk,1:num_bins2d))
111 allocate (regcoeff3(1:nk,1:nk,1:num_bins2d))
113 read (be_unit) regcoeff1
114 read (be_unit) regcoeff2
115 read (be_unit) regcoeff3
117 ! 1.2 Fill regression coeff. array
120 allocate (be%reg_chi(1:jy,1:kz))
121 allocate (be%reg_ps (1:jy,1:kz))
122 allocate (be%reg_t (1:jy,1:kz,1:kz))
127 be%reg_chi(j,k) = regcoeff1(b)
133 be%reg_ps(j,k) = regcoeff2(k,b)
141 be%reg_t(j,i,k) = regcoeff3(i,k,b)
146 deallocate (regcoeff1)
147 deallocate (regcoeff2)
148 deallocate (regcoeff3)
151 ! 1.3 Domain_averaged regression coefficients
153 if (.not.lat_stats_option) then
154 write (unit=message(4), fmt='(3x, a)') &
155 'Using the averaged regression coefficients for unbalanced part'
161 avg= avg + be%reg_ps (j,k)/float(num_bins2d)
162 avg2= avg2 + be%reg_chi (j,k)/float(num_bins2d)
167 be%reg_chi (j,k)=avg2
176 avg3= avg3 + be%reg_t (j,k,m)/float(num_bins2d)
185 write (unit=message(4), fmt='(3x, a)') &
186 'Using the latitude-dependent regression coefficients for unbalanced part'
189 call da_message(message(1:4))
191 ! 2.0 Load the eigenvector and eigenvalue
192 allocate (be1_eval_loc (1:jy,1:nk))
193 allocate (be2_eval_loc (1:jy,1:nk))
194 allocate (be3_eval_loc (1:jy,1:nk))
195 allocate (be4_eval_loc (1:jy,1:nk))
196 allocate (be5_eval_loc (1:jy,1:1))
198 if (vert_corr == vert_corr_2) then
200 allocate (be1_eval_glo(1:nk))
201 allocate (be2_eval_glo(1:nk))
202 allocate (be3_eval_glo(1:nk))
203 allocate (be4_eval_glo(1:nk))
204 allocate (be5_eval_glo(1:1))
206 allocate (be1_evec_loc(1:jy,1:nk,1:nk))
207 allocate (be2_evec_loc(1:jy,1:nk,1:nk))
208 allocate (be3_evec_loc(1:jy,1:nk,1:nk))
209 allocate (be4_evec_loc(1:jy,1:nk,1:nk))
210 allocate (be5_evec_loc(1:jy,1: 1,1: 1))
212 allocate (be1_evec_glo(1:nk,1:nk))
213 allocate (be2_evec_glo(1:nk,1:nk))
214 allocate (be3_evec_glo(1:nk,1:nk))
215 allocate (be4_evec_glo(1:nk,1:nk))
216 allocate (be5_evec_glo(1:1,1:1))
219 ! 2.2 Read in the eigenvector and eigenvalue
221 ! 2.2.1 Control variable 1 (psi)
223 read (be_unit) variable
224 read (be_unit) nk, num_bins2d
225 read (be_unit) be1_evec_glo
226 read (be_unit) be1_eval_glo
227 allocate (evec_loc(1:nk,1:nk,1:num_bins2d))
228 allocate (eval_loc(1:nk, 1:num_bins2d))
229 read (be_unit) evec_loc
230 read (be_unit) eval_loc
231 if (variable(1:3) /= 'psi') then
232 message(1)=' Variable mismatch while transfering eigen values from BE file '
233 write (unit=message(2),fmt='(A,A)') ' Expected psi but got ',variable
234 call da_error(__FILE__,__LINE__,message(1:2))
236 be % v1 % name = variable
239 be1_evec_loc(j,1:kz,1:kz) = evec_loc(1:kz,1:kz,b)
240 be1_eval_loc(j,1:kz ) = eval_loc(1:kz,b)
243 ! 2.2.2 Control variable 2 (chi_u)
245 read (be_unit) variable
246 read (be_unit) nk, num_bins2d
247 read (be_unit) be2_evec_glo
248 read (be_unit) be2_eval_glo
249 read (be_unit) evec_loc
250 read (be_unit) eval_loc
251 if (variable(1:5) /= 'chi_u') then
252 message(1)=' Variable mismatch while transfering eigen values from BE file '
253 write (unit=message(2),fmt='(A,A)') ' Expected chi_u but got ',variable
254 call da_error(__FILE__,__LINE__,message(1:2))
256 be % v2 % name = variable
259 be2_evec_loc(j,1:kz,1:kz) = evec_loc(1:kz,1:kz,b)
260 be2_eval_loc(j,1:kz ) = eval_loc(1:kz,b)
263 ! 2.2.3 Control variable 3 (t_u)
264 read (be_unit) variable
265 read (be_unit) nk, num_bins2d
266 read (be_unit) be3_evec_glo
267 read (be_unit) be3_eval_glo
268 read (be_unit) evec_loc
269 read (be_unit) eval_loc
270 if (variable(1:3) /= 't_u') then
271 message(1)=' Variable mismatch while transfering eigen values from BE file '
272 write (unit=message(2),fmt='(A,A)') ' Expected t_u but got ',variable
273 call da_error(__FILE__,__LINE__,message(1:2))
275 be % v3 % name = variable
278 be3_evec_loc(j,1:kz,1:kz) = evec_loc(1:kz,1:kz,b)
279 be3_eval_loc(j,1:kz ) = eval_loc(1:kz,b)
282 ! 2.2.4 Control variable 4 (q/qsg)
284 read (be_unit) variable
285 read (be_unit) nk, num_bins2d
286 read (be_unit) be4_evec_glo
287 read (be_unit) be4_eval_glo
288 read (be_unit) evec_loc
289 read (be_unit) eval_loc
290 if (variable(1:3) /= 'rh') then
291 message(1)=' Variable mismatch while transfering eigen values from BE file '
292 write (unit=message(2),fmt='(A,A)') ' Expected rh but got ',variable
293 call da_error(__FILE__,__LINE__,message(1:2))
295 be % v4 % name = variable
298 be4_evec_loc(j,1:kz,1:kz) = evec_loc(1:kz,1:kz,b)
299 be4_eval_loc(j,1:kz ) = eval_loc(1:kz,b)
302 deallocate (evec_loc)
303 deallocate (eval_loc)
305 ! 2.2.5 Control variable ps_u
307 read (be_unit) variable
308 read (be_unit) nk_2d, num_bins2d
309 allocate (evec_loc(1:nk_2d,1:nk_2d,1:num_bins2d))
310 allocate (eval_loc(1:nk_2d, 1:num_bins2d))
311 read (be_unit) be5_evec_glo
312 read (be_unit) be5_eval_glo
313 read (be_unit) evec_loc
314 read (be_unit) eval_loc
315 if (variable(1:4) /= 'ps_u') then
316 message(1)=' Variable mismatch while transfering eigen values from BE file '
317 write (unit=message(2),fmt='(A,A)') ' Expected ps_u but got ',variable
318 call da_error(__FILE__,__LINE__,message(1:2))
320 be % v5 % name = variable
323 be5_evec_loc(j,1:1,1:1) = evec_loc(1:1,1:1,b)
324 be5_eval_loc(j,1:1 ) = eval_loc(1:1,b)
327 deallocate (evec_loc)
328 deallocate (eval_loc)
330 ! 3.0 Check and get the truncated number of the vertical modes
331 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
333 if (vert_corr == vert_corr_2) then
335 ! 3.1 Perform checks on eigenvectors:
337 if (test_statistics) then
338 call da_check_eof_decomposition(be1_eval_glo(:), be1_evec_glo(:,:), be % v1 % name)
339 call da_check_eof_decomposition(be2_eval_glo(:), be2_evec_glo(:,:), be % v2 % name)
340 call da_check_eof_decomposition(be3_eval_glo(:), be3_evec_glo(:,:), be % v3 % name)
341 call da_check_eof_decomposition(be4_eval_glo(:), be4_evec_glo(:,:), be % v4 % name)
344 ! 3.2 Truncate in vertical:
346 call da_get_vertical_truncation(max_vert_var1, be1_eval_glo(:), be % v1)
347 call da_get_vertical_truncation(max_vert_var2, be2_eval_glo(:), be % v2)
348 call da_get_vertical_truncation(max_vert_var3, be3_eval_glo(:), be % v3)
349 call da_get_vertical_truncation(max_vert_var4, be4_eval_glo(:), be % v4)
353 write (unit=stdout,fmt=*) ' '
359 be % v1 % mz = xb % mkz
360 be % v2 % mz = xb % mkz
361 be % v3 % mz = xb % mkz
362 be % v4 % mz = xb % mkz
363 be % v5 % mz = xb % mkz
367 ! 4.0 Initialise control variable space components of header:
368 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
370 ! 4.1 Compute the size of the control variables
375 ! 4.2 Transfer errors to error structure:
377 call da_allocate_background_errors(jy, kz, be1_eval_glo, be1_evec_glo, be1_eval_loc, &
378 be1_evec_loc, be % v1)
379 call da_allocate_background_errors(jy, kz, be2_eval_glo, be2_evec_glo, be2_eval_loc, &
380 be2_evec_loc, be % v2)
381 call da_allocate_background_errors(jy, kz, be3_eval_glo, be3_evec_glo, be3_eval_loc, &
382 be3_evec_loc, be % v3)
383 call da_allocate_background_errors(jy, kz, be4_eval_glo, be4_evec_glo, be4_eval_loc, &
384 be4_evec_loc, be % v4)
385 ! 4.2.1 transfer the ps_u variance to be % v5:
387 call da_allocate_background_errors(jy, 1, be5_eval_glo, be5_evec_glo, be5_eval_loc, &
388 be5_evec_loc, be % v5)
390 if (print_detail_be) then
391 write (unit=stdout,fmt='(3x,a,i10)') "b) Finished eigenvector processing!"
394 ! 5.0 Load the scale lengths
395 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
397 ! 5.1 allocate the array for scale lengths
399 allocate (be1_rf_lengthscale(1:nk))
400 allocate (be2_rf_lengthscale(1:nk))
401 allocate (be3_rf_lengthscale(1:nk))
402 allocate (be4_rf_lengthscale(1:nk))
403 allocate (be5_rf_lengthscale(1:nk))
405 ! 5.2 read in the scale lengths
407 read (be_unit) variable
408 read (be_unit) be1_rf_lengthscale
410 read (be_unit) variable
411 read (be_unit) be2_rf_lengthscale
413 read (be_unit) variable
414 read (be_unit) be3_rf_lengthscale
416 read (be_unit) variable
417 read (be_unit) be4_rf_lengthscale
419 read (be_unit) variable
420 read (be_unit) be5_rf_lengthscale(1:1)
421 be%v5%name = variable
423 ! 5.3 Convert the scale lengths in the real distance (meter)
425 be1_rf_lengthscale(1:nk) = be1_rf_lengthscale(1:nk) * xb%ds
426 be2_rf_lengthscale(1:nk) = be2_rf_lengthscale(1:nk) * xb%ds
427 be3_rf_lengthscale(1:nk) = be3_rf_lengthscale(1:nk) * xb%ds
428 be4_rf_lengthscale(1:nk) = be4_rf_lengthscale(1:nk) * xb%ds
429 be5_rf_lengthscale(1:1) = be5_rf_lengthscale(1:1) * xb%ds
431 ! 6.0 Perform checks on eigenvectors with be data structure:
432 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
434 if (test_statistics) then
435 call da_check_eof_decomposition(be%v1%val_g(:), be%v1%evec_g(:,:),&
437 call da_check_eof_decomposition(be%v2%val_g(:), be%v2%evec_g(:,:),&
439 call da_check_eof_decomposition(be%v3%val_g(:), be%v3%evec_g(:,:),&
441 call da_check_eof_decomposition(be%v4%val_g(:), be%v4%evec_g(:,:),&
445 ! 6.2 Close the be unit
448 call da_free_unit(be_unit)
450 ! 7.0 Apply empirical and recursive filter rescaling factor:
451 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
453 call da_rescale_background_errors(var_scaling1(1), len_scaling1(1), &
454 xb % ds, be1_rf_lengthscale, be % v1)
455 call da_rescale_background_errors(var_scaling2(1), len_scaling2(1), &
456 xb % ds, be2_rf_lengthscale, be % v2)
457 call da_rescale_background_errors(var_scaling3(1), len_scaling3(1), &
458 xb % ds, be3_rf_lengthscale, be % v3)
459 call da_rescale_background_errors(var_scaling4(1), len_scaling4(1), &
460 xb % ds, be4_rf_lengthscale, be % v4)
461 call da_rescale_background_errors(var_scaling5(1), len_scaling5(1), &
462 xb % ds, be5_rf_lengthscale, be % v5)
464 ! 8.0 deallocate input model state:
465 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
467 deallocate (be1_eval_loc)
468 deallocate (be2_eval_loc)
469 deallocate (be3_eval_loc)
470 deallocate (be4_eval_loc)
471 deallocate (be5_eval_loc)
473 if (vert_corr == vert_corr_2) then
474 deallocate (be1_eval_glo)
475 deallocate (be2_eval_glo)
476 deallocate (be3_eval_glo)
477 deallocate (be4_eval_glo)
478 deallocate (be5_eval_glo)
480 deallocate (be1_evec_loc)
481 deallocate (be2_evec_loc)
482 deallocate (be3_evec_loc)
483 deallocate (be4_evec_loc)
484 deallocate (be5_evec_loc)
486 deallocate (be1_evec_glo)
487 deallocate (be2_evec_glo)
488 deallocate (be3_evec_glo)
489 deallocate (be4_evec_glo)
490 deallocate (be5_evec_glo)
497 if (be % ne > 0) then
498 be % alpha % mz = be % ne
499 be % alpha % name = 'alpha'
501 allocate (be5_eval_loc (1:1,1:num_bins2d))
502 allocate (be5_eval_glo(1:1))
503 allocate (be5_evec_loc(1:1,1:1,1:num_bins2d))
504 allocate (be5_evec_glo(1:1,1:1))
506 ! Transfer the alpha standard deviation to be % alpha:
507 allocate (be % alpha % val(1:jy,1:be % ne))
508 allocate (be % alpha % evec(1:jy,1:kz,1:be % ne))
509 allocate (be % alpha % rf_alpha(1:be % ne))
511 be % alpha % val(1:jy,1:be % ne) = alpha_std_dev
512 be % alpha % evec(1:jy,1:kz,1:be % ne) = 1.0
513 be % alpha % rf_alpha(1:be % ne) = 1.0
515 ! Include alpha lengthscale info:
516 allocate (alpha_rf_lengthscale(1:be % ne))
517 alpha_rf_lengthscale(:) = 1000.0 * alpha_corr_scale ! Convert km to m.
519 call da_rescale_background_errors(1.0, 1.0, &
520 xb % ds, alpha_rf_lengthscale, be % alpha)
525 if (trace_use) call da_trace_exit("da_setup_be_nmm_regional")
527 end subroutine da_setup_be_nmm_regional