da_get_vertical_truncation.inc
References to this file elsewhere.
1 subroutine da_get_vertical_truncation( max_vert_var, eigenval, be_sub)
2
3 !---------------------------------------------------------------------------
4 ! Purpose: Calculate vertical mode truncation from explained variance.
5 !
6 ! Method: Calculate cumulative variance and compare with limit.
7 !---------------------------------------------------------------------------
8
9 implicit none
10
11 real, intent(in) :: max_vert_var ! Vertical variance limit.
12 real, intent(in) :: eigenval(:) ! Global eigenvaluess.
13 type(be_subtype), intent(inout) :: be_sub ! Back. error sub type.
14
15 integer :: kz ! # vertical levels.
16 integer :: k ! Loop counter.
17 real :: tot_variance ! Total variance.
18 real :: cum_variance ! Cumulative variance.
19 character(LEN = 6) :: name ! Variable name.
20
21 if (trace_use_dull) call da_trace_entry("da_get_vertical_truncation")
22
23
24 !---------------------------------------------------------------------------
25 ! [1.0] Initialise:
26 !---------------------------------------------------------------------------
27
28 kz = size( eigenval(:))
29 name = trim(be_sub % name)
30
31 !---------------------------------------------------------------------------
32 ! [2.0] Calculate vertical truncation:
33 !---------------------------------------------------------------------------
34
35 if (max_vert_var >= 100.0) then
36
37 ! [2.1] No truncation:
38 be_sub % mz = kz
39
40 ! Disregard zero/-ve eigenvalues(which should be very small and only
41 ! appear if statistics have been interpolated between domains):
42
43 do k = 1, kz
44 if (eigenval(k) <= 0.0) then
45 be_sub % mz = k - 1
46 exit
47 end if
48 end do
49 else
50
51 ! [2.2] Calculate cumulative variance and truncate:
52
53 tot_variance = sum( eigenval(1:kz))
54 cum_variance = 0.0
55
56 do k = 1, kz
57 cum_variance = cum_variance + eigenval(k)
58
59 if (eigenval(k) <= 0.0) then
60 be_sub % mz = k - 1
61 exit
62 end if
63
64 if (cum_variance/tot_variance >= 0.01 * max_vert_var) then
65 be_sub % mz = k
66 exit
67 end if
68 end do
69
70 if (max_vert_var == 0.0) be_sub % mz = 0
71
72 end if
73
74 write(unit=stdout,fmt='(A,A6,A3,I3,A1,f7.2,A2)') &
75 'Vertical truncation for ', name, &
76 ' = ', be_sub % mz, '(', &
77 max_vert_var, '%)'
78 write (unit=stdout,fmt='(A)') " "
79
80 if (trace_use_dull) call da_trace_exit("da_get_vertical_truncation")
81
82 end subroutine da_get_vertical_truncation
83
84