MONC
swapsmooth.F90
Go to the documentation of this file.
1 
6  use grids_mod, only : x_index, y_index, z_index
8  implicit none
9 
10 #ifndef TEST_MODE
11  private
12 #endif
13 
14  logical :: mean_profiles_active=.false.
15 
17 
18 contains
19 
23  swapsmooth_get_descriptor%name="swap_smooth"
24  swapsmooth_get_descriptor%version=0.1
27  end function swapsmooth_get_descriptor
28 
31  subroutine initialisation_callback(current_state)
32  type(model_state_type), target, intent(inout) :: current_state
33 
34 #ifdef U_ACTIVE
35  mean_profiles_active=allocated(current_state%global_grid%configuration%vertical%olubar)
36  return
37 #endif
38 #ifdef V_ACTIVE
39  mean_profiles_active=allocated(current_state%global_grid%configuration%vertical%olvbar)
40  return
41 #endif
42  if (current_state%th%active) then
43  mean_profiles_active=allocated(current_state%global_grid%configuration%vertical%olthbar)
44  return
45  end if
46  if (current_state%number_q_fields .gt. 0) then
47  mean_profiles_active=allocated(current_state%global_grid%configuration%vertical%olqbar)
48  return
49  end if
50  end subroutine initialisation_callback
51 
54  subroutine timestep_callback(current_state)
55  type(model_state_type), target, intent(inout) :: current_state
56 
57  if (.not. current_state%halo_column) then
58  if (current_state%field_stepping == forward_stepping) then
59  call swap_and_smooth_classic(current_state, .false.)
60  else
61  ! Centred stepping
62  call swap_and_smooth_robert_filter(current_state)
63  end if
64  end if
65 
66  if (mean_profiles_active .and. current_state%last_timestep_column) then
67  if (current_state%field_stepping == forward_stepping) then
68  call classic_for_average_profiles(current_state, .false.)
69  else
70  call robert_filter_for_average_profiles(current_state)
71  end if
72  end if
73  end subroutine timestep_callback
74 
78  subroutine swap_and_smooth_classic(current_state, old_smoother)
79  type(model_state_type), intent(inout) :: current_state
80  logical, intent(in) :: old_smoother
81 
82  integer :: y_index, x_index, k, n
83  real(kind=default_precision) :: c1, c2, existing_value
84 
85  if (old_smoother) then
86  c1 = 1.0_default_precision - current_state%tsmth
87  c2 = 2.0_default_precision * current_state%tsmth - 1.0_default_precision
88  else
89  c1 = 1.0_default_precision
90  c2 = -1.0_default_precision
91  end if
92 
93  x_index=current_state%column_local_x
94  y_index=current_state%column_local_y
95 
96  do k=1,current_state%global_grid%size(z_index)
97 #ifdef U_ACTIVE
98  existing_value = current_state%u%data(k,y_index,x_index) + current_state%zu%data(k,y_index,x_index)
99  current_state%u%data(k,y_index,x_index)=existing_value * c1 + current_state%u%data(k,y_index,x_index) * c2
100  current_state%zu%data(k,y_index,x_index)=existing_value - current_state%u%data(k,y_index,x_index)
101 #endif
102 #ifdef V_ACTIVE
103  existing_value = current_state%v%data(k,y_index,x_index) + current_state%zv%data(k,y_index,x_index)
104  current_state%v%data(k,y_index,x_index)=existing_value * c1 + current_state%v%data(k,y_index,x_index) * c2
105  current_state%zv%data(k,y_index,x_index)=existing_value - current_state%v%data(k,y_index,x_index)
106 #endif
107 #ifdef W_ACTIVE
108  existing_value = current_state%w%data(k,y_index,x_index) + current_state%zw%data(k,y_index,x_index)
109  current_state%w%data(k,y_index,x_index)=existing_value * c1 + current_state%w%data(k,y_index,x_index) * c2
110  current_state%zw%data(k,y_index,x_index)=existing_value - current_state%w%data(k,y_index,x_index)
111 #endif
112  if (current_state%th%active) then
113  existing_value = current_state%th%data(k,y_index,x_index) + current_state%zth%data(k,y_index,x_index)
114  current_state%th%data(k,y_index,x_index)=existing_value * c1 + current_state%th%data(k,y_index,x_index) * c2
115  current_state%zth%data(k,y_index,x_index)=existing_value - current_state%th%data(k,y_index,x_index)
116  end if
117  do n=1,current_state%number_q_fields
118  if (current_state%q(n)%active) then
119  existing_value = current_state%q(n)%data(k,y_index,x_index) + current_state%zq(n)%data(k,y_index,x_index)
120  current_state%q(n)%data(k,y_index,x_index)=existing_value * c1 + current_state%q(n)%data(k,y_index,x_index) * c2
121  current_state%zq(n)%data(k,y_index,x_index)=existing_value - current_state%q(n)%data(k,y_index,x_index)
122  end if
123  end do
124  end do
125  end subroutine swap_and_smooth_classic
126 
129  subroutine swap_and_smooth_robert_filter(current_state)
130  type(model_state_type), intent(inout) :: current_state
131 
132  integer :: y_index, x_index, k, n
133  real(kind=default_precision) :: c1, c2, existing_value
134 
135  x_index=current_state%column_local_x
136  y_index=current_state%column_local_y
137 
138  c1 = 1.0_default_precision - 2.0_default_precision*current_state%tsmth
139  c2 = current_state%tsmth
140 
141  do k=1,current_state%global_grid%size(z_index)
142 #ifdef U_ACTIVE
143  existing_value = current_state%u%data(k,y_index,x_index)
144  current_state%u%data(k,y_index,x_index)=current_state%zu%data(k,y_index,x_index)
145  current_state%zu%data(k,y_index,x_index)=c1*existing_value+c2*(current_state%u%data(k, y_index, x_index)+&
146  current_state%savu%data(k,y_index,x_index) -current_state%ugal)
147 #endif
148 #ifdef V_ACTIVE
149  existing_value = current_state%v%data(k,y_index,x_index)
150  current_state%v%data(k,y_index,x_index)=current_state%zv%data(k,y_index,x_index)
151  current_state%zv%data(k,y_index,x_index)=c1*existing_value+c2*(current_state%v%data(k, y_index, x_index)+&
152  current_state%savv%data(k,y_index,x_index)-current_state%vgal)
153 #endif
154 #ifdef W_ACTIVE
155  existing_value = current_state%w%data(k,y_index,x_index)
156  current_state%w%data(k,y_index,x_index)=current_state%zw%data(k,y_index,x_index)
157  current_state%zw%data(k,y_index,x_index)=c1*existing_value+c2*(current_state%w%data(k, y_index, x_index)+&
158  current_state%savw%data(k,y_index,x_index))
159 #endif
160  if (current_state%th%active) then
161  ! Uses the partial smooth of theta from stepfields
162  existing_value = current_state%zth%data(k,y_index,x_index)
163  current_state%zth%data(k,y_index,x_index)=current_state%th%data(k,y_index,x_index) + current_state%tsmth * existing_value
164  current_state%th%data(k,y_index,x_index)=existing_value
165  end if
166  do n=1, current_state%number_q_fields
167  if (current_state%q(n)%active) then
168  ! Uses the partial smooth of q from stepfields
169  existing_value = current_state%zq(n)%data(k,y_index,x_index)
170  current_state%zq(n)%data(k,y_index,x_index)=current_state%q(n)%data(k,y_index,x_index)+&
171  current_state%tsmth * existing_value
172  current_state%q(n)%data(k,y_index,x_index)=existing_value
173  end if
174  end do
175  end do
176  end subroutine swap_and_smooth_robert_filter
177 
180  subroutine classic_for_average_profiles(current_state, old_smoother)
181  type(model_state_type), intent(inout) :: current_state
182  logical, intent(in) :: old_smoother
183 
184  integer :: k, n
185  real(kind=default_precision) :: c1, c2
186 
187  if (old_smoother) then
188  c1 = 1.0_default_precision - current_state%tsmth
189  c2 = 2.0_default_precision * current_state%tsmth - 1.0_default_precision
190  else
191  c1 = 1.0_default_precision
192  c2 = -1.0_default_precision
193  end if
194 
195  do k=1,current_state%global_grid%size(z_index)
196 #ifdef U_ACTIVE
197  current_state%global_grid%configuration%vertical%olzubar(k)=current_state%global_grid%configuration%vertical%olubar(k) +&
198  current_state%global_grid%configuration%vertical%olzubar(k)
199  current_state%global_grid%configuration%vertical%olubar(k)=current_state%global_grid%configuration%vertical%olzubar(k) *&
200  c1 + current_state%global_grid%configuration%vertical%olubar(k) * c2
201  current_state%global_grid%configuration%vertical%olzubar(k)=current_state%global_grid%configuration%vertical%olzubar(k) -&
202  current_state%global_grid%configuration%vertical%olubar(k)
203 #endif
204 #ifdef V_ACTIVE
205  current_state%global_grid%configuration%vertical%olzvbar(k)=current_state%global_grid%configuration%vertical%olvbar(k) +&
206  current_state%global_grid%configuration%vertical%olzvbar(k)
207  current_state%global_grid%configuration%vertical%olvbar(k)=current_state%global_grid%configuration%vertical%olzvbar(k) *&
208  c1 + current_state%global_grid%configuration%vertical%olvbar(k) * c2
209  current_state%global_grid%configuration%vertical%olzvbar(k)=current_state%global_grid%configuration%vertical%olzvbar(k) -&
210  current_state%global_grid%configuration%vertical%olvbar(k)
211 #endif
212  if (current_state%th%active) then
213  current_state%global_grid%configuration%vertical%olzthbar(k)=current_state%global_grid%configuration%vertical%olthbar(k)+&
214  current_state%global_grid%configuration%vertical%olzthbar(k)
215  current_state%global_grid%configuration%vertical%olthbar(k)=current_state%global_grid%configuration%vertical%olzthbar(k)*&
216  c1 + current_state%global_grid%configuration%vertical%olthbar(k) * c2
217  current_state%global_grid%configuration%vertical%olzthbar(k)=&
218  current_state%global_grid%configuration%vertical%olzthbar(k)-&
219  current_state%global_grid%configuration%vertical%olthbar(k)
220  end if
221  if (current_state%number_q_fields .gt. 0) then
222  do n=1, current_state%number_q_fields
223  current_state%global_grid%configuration%vertical%olzqbar(k,n)=&
224  current_state%global_grid%configuration%vertical%olqbar(k,n)+&
225  current_state%global_grid%configuration%vertical%olzqbar(k,n)
226  current_state%global_grid%configuration%vertical%olqbar(k,n)=&
227  current_state%global_grid%configuration%vertical%olzqbar(k,n)*&
228  c1 + current_state%global_grid%configuration%vertical%olqbar(k,n) * c2
229  current_state%global_grid%configuration%vertical%olzqbar(k,n)=&
230  current_state%global_grid%configuration%vertical%olzqbar(k,n)-&
231  current_state%global_grid%configuration%vertical%olqbar(k,n)
232  end do
233  end if
234  end do
235  end subroutine classic_for_average_profiles
236 
239  subroutine robert_filter_for_average_profiles(current_state)
240  type(model_state_type), intent(inout) :: current_state
241 
242  integer :: k, n
243  real(kind=default_precision) :: c1, c2, existing_value
244 
245  c1 = 1.0_default_precision - 2.0_default_precision*current_state%tsmth
246  c2 = current_state%tsmth
247 
248  do k=1,current_state%global_grid%size(z_index)
249 #ifdef U_ACTIVE
250  existing_value=current_state%global_grid%configuration%vertical%olubar(k)
251  current_state%global_grid%configuration%vertical%olubar(k)=current_state%global_grid%configuration%vertical%olzubar(k)
252  current_state%global_grid%configuration%vertical%olzubar(k)=c1*existing_value+c2*&
253  (current_state%global_grid%configuration%vertical%olubar(k) + &
254  current_state%global_grid%configuration%vertical%savolubar(k))
255 #endif
256 #ifdef V_ACTIVE
257  existing_value=current_state%global_grid%configuration%vertical%olvbar(k)
258  current_state%global_grid%configuration%vertical%olvbar(k)=current_state%global_grid%configuration%vertical%olzvbar(k)
259  current_state%global_grid%configuration%vertical%olzvbar(k)=c1*existing_value+c2*&
260  (current_state%global_grid%configuration%vertical%olvbar(k) + &
261  current_state%global_grid%configuration%vertical%savolvbar(k))
262 #endif
263  if (current_state%th%active) then
264  existing_value=current_state%global_grid%configuration%vertical%olzthbar(k)
265  current_state%global_grid%configuration%vertical%olzthbar(k)=&
266  current_state%global_grid%configuration%vertical%olthbar(k) + current_state%tsmth * existing_value
267  current_state%global_grid%configuration%vertical%olthbar(k)=existing_value
268  end if
269  if (current_state%number_q_fields .gt. 0) then
270  do n=1, current_state%number_q_fields
271  existing_value=current_state%global_grid%configuration%vertical%olzqbar(k,n)
272  current_state%global_grid%configuration%vertical%olzqbar(k,n)=&
273  current_state%global_grid%configuration%vertical%olqbar(k,n) + current_state%tsmth * existing_value
274  current_state%global_grid%configuration%vertical%olqbar(k,n)=existing_value
275  end do
276  end if
277  end do
278  end subroutine robert_filter_for_average_profiles
279 end module swapsmooth_mod
swapsmooth_mod::classic_for_average_profiles
subroutine classic_for_average_profiles(current_state, old_smoother)
Does swapping and smoothing (using classic algorithm) for the average profiles (the bars)
Definition: swapsmooth.F90:181
grids_mod::x_index
integer, parameter, public x_index
Definition: grids.F90:14
grids_mod::y_index
integer, parameter, public y_index
Definition: grids.F90:14
monc_component_mod
Interfaces and types that MONC components must specify.
Definition: monc_component.F90:6
swapsmooth_mod::robert_filter_for_average_profiles
subroutine robert_filter_for_average_profiles(current_state)
Does swapping and smoothing (using robert filter algorithm) for the average profiles (the bars)
Definition: swapsmooth.F90:240
swapsmooth_mod::swapsmooth_get_descriptor
type(component_descriptor_type) function, public swapsmooth_get_descriptor()
Provides the descriptor back to the caller and is used in component registration.
Definition: swapsmooth.F90:23
grids_mod::z_index
integer, parameter, public z_index
Grid index parameters.
Definition: grids.F90:14
swapsmooth_mod
Does the swapping and smoothing which is called for each column as part of the pressure-terms group o...
Definition: swapsmooth.F90:3
state_mod::model_state_type
The ModelState which represents the current state of a run.
Definition: state.F90:39
state_mod::forward_stepping
integer, parameter, public forward_stepping
Definition: state.F90:15
swapsmooth_mod::swap_and_smooth_classic
subroutine swap_and_smooth_classic(current_state, old_smoother)
Classic swap and smooth based upon the old or no smoothing.
Definition: swapsmooth.F90:79
datadefn_mod
Contains common definitions for the data and datatypes used by MONC.
Definition: datadefn.F90:2
swapsmooth_mod::timestep_callback
subroutine timestep_callback(current_state)
Called for each non halo timestep column and will perform swapping and smoothing as required on that ...
Definition: swapsmooth.F90:55
swapsmooth_mod::swap_and_smooth_robert_filter
subroutine swap_and_smooth_robert_filter(current_state)
Swap and smooth with a Robert filter.
Definition: swapsmooth.F90:130
swapsmooth_mod::initialisation_callback
subroutine initialisation_callback(current_state)
Initialises the swap and smooth component.
Definition: swapsmooth.F90:32
grids_mod
Functionality to support the different types of grid and abstraction between global grids and local o...
Definition: grids.F90:5
swapsmooth_mod::mean_profiles_active
logical mean_profiles_active
Whether or not mean profiles need smoothing.
Definition: swapsmooth.F90:14
monc_component_mod::component_descriptor_type
Description of a component.
Definition: monc_component.F90:42
datadefn_mod::default_precision
integer, parameter, public default_precision
MPI communication type which we use for the prognostic and calculation data.
Definition: datadefn.F90:17
state_mod
The model state which represents the current state of a run.
Definition: state.F90:2