MONC
viscosity.F90
Go to the documentation of this file.
1 
10  use grids_mod, only : z_index, x_index, y_index
16 
17  implicit none
18 
19 #ifndef TEST_MODE
20  private
21 #endif
22 
23  real(kind=default_precision), dimension(:), allocatable :: u_viscosity, v_viscosity, w_viscosity
24 
25  ! Local tendency diagnostic variables for this component
26  ! 3D tendency fields and logicals for their use
27  real(kind=default_precision), dimension(:,:,:), allocatable :: &
30  ! Local mean tendency profile fields and logicals for their use
31  real(kind=default_precision), dimension(:), allocatable :: &
34 
36 
38 
39 contains
40 
44  viscosity_get_descriptor%name="viscosity"
45  viscosity_get_descriptor%version=0.1
49 
52  allocate(viscosity_get_descriptor%published_fields(3+3+3))
53 
54  viscosity_get_descriptor%published_fields(1)="u_viscosity"
55  viscosity_get_descriptor%published_fields(2)="v_viscosity"
56  viscosity_get_descriptor%published_fields(3)="w_viscosity"
57 
58  viscosity_get_descriptor%published_fields(3+1)= "tend_u_viscosity_3d_local"
59  viscosity_get_descriptor%published_fields(3+2)= "tend_v_viscosity_3d_local"
60  viscosity_get_descriptor%published_fields(3+3)= "tend_w_viscosity_3d_local"
61 
62  viscosity_get_descriptor%published_fields(3+3+1)= "tend_u_viscosity_profile_total_local"
63  viscosity_get_descriptor%published_fields(3+3+2)= "tend_v_viscosity_profile_total_local"
64  viscosity_get_descriptor%published_fields(3+3+3)= "tend_w_viscosity_profile_total_local"
65 
66  end function viscosity_get_descriptor
67 
72  subroutine field_information_retrieval_callback(current_state, name, field_information)
73  type(model_state_type), target, intent(inout) :: current_state
74  character(len=*), intent(in) :: name
75  type(component_field_information_type), intent(out) :: field_information
76  integer :: strcomp
77 
78  ! Field description is the same regardless of the specific field being retrieved
79  field_information%field_type=component_array_field_type
80  field_information%data_type=component_double_data_type
81  field_information%number_dimensions=1
82  field_information%dimension_sizes(1)=current_state%local_grid%size(z_index)
83  field_information%enabled=.true.
84 
85  ! Field information for 3d
86  strcomp=index(name, "viscosity_3d_local")
87  if (strcomp .ne. 0) then
88  field_information%field_type=component_array_field_type
89  field_information%number_dimensions=3
90  field_information%dimension_sizes(1)=current_state%local_grid%size(z_index)
91  field_information%dimension_sizes(2)=current_state%local_grid%size(y_index)
92  field_information%dimension_sizes(3)=current_state%local_grid%size(x_index)
93  field_information%data_type=component_double_data_type
94 
95  if (name .eq. "tend_u_viscosity_3d_local") then
96  field_information%enabled=l_tend_3d_u
97  else if (name .eq. "tend_v_viscosity_3d_local") then
98  field_information%enabled=l_tend_3d_v
99  else if (name .eq. "tend_w_viscosity_3d_local") then
100  field_information%enabled=l_tend_3d_w
101  else
102  field_information%enabled=.true.
103  end if
104 
105  end if !end 3d check
106 
107  ! Field information for profiles
108  strcomp=index(name, "viscosity_profile_total_local")
109  if (strcomp .ne. 0) then
110  field_information%field_type=component_array_field_type
111  field_information%number_dimensions=1
112  field_information%dimension_sizes(1)=current_state%local_grid%size(z_index)
113  field_information%data_type=component_double_data_type
114 
115  if (name .eq. "tend_u_viscosity_profile_total_local") then
116  field_information%enabled=l_tend_pr_tot_u
117  else if (name .eq. "tend_v_viscosity_profile_total_local") then
118  field_information%enabled=l_tend_pr_tot_v
119  else if (name .eq. "tend_w_viscosity_profile_total_local") then
120  field_information%enabled=l_tend_pr_tot_w
121  else
122  field_information%enabled=.true.
123  end if
124 
125  end if !end profile check
126 
128 
129 
134  subroutine field_value_retrieval_callback(current_state, name, field_value)
135  type(model_state_type), target, intent(inout) :: current_state
136  character(len=*), intent(in) :: name
137  type(component_field_value_type), intent(out) :: field_value
138 
139  if (name .eq. "u_viscosity") then
140  allocate(field_value%real_1d_array(size(u_viscosity)), source=u_viscosity)
141  else if (name .eq. "v_viscosity") then
142  allocate(field_value%real_1d_array(size(v_viscosity)), source=v_viscosity)
143  else if (name .eq. "w_viscosity") then
144  allocate(field_value%real_1d_array(size(w_viscosity)), source=w_viscosity)
145 
146  ! 3d Tendency Fields
147  else if (name .eq. "tend_u_viscosity_3d_local" .and. allocated(tend_3d_u)) then
148  call set_published_field_value(field_value, real_3d_field=tend_3d_u)
149  else if (name .eq. "tend_v_viscosity_3d_local" .and. allocated(tend_3d_v)) then
150  call set_published_field_value(field_value, real_3d_field=tend_3d_v)
151  else if (name .eq. "tend_w_viscosity_3d_local" .and. allocated(tend_3d_w)) then
152  call set_published_field_value(field_value, real_3d_field=tend_3d_w)
153 
154  ! Profile Tendency Fields
155  else if (name .eq. "tend_u_viscosity_profile_total_local" .and. allocated(tend_pr_tot_u)) then
156  call set_published_field_value(field_value, real_1d_field=tend_pr_tot_u)
157  else if (name .eq. "tend_v_viscosity_profile_total_local" .and. allocated(tend_pr_tot_v)) then
158  call set_published_field_value(field_value, real_1d_field=tend_pr_tot_v)
159  else if (name .eq. "tend_w_viscosity_profile_total_local" .and. allocated(tend_pr_tot_w)) then
160  call set_published_field_value(field_value, real_1d_field=tend_pr_tot_w)
161  end if
162 
163 
164  end subroutine field_value_retrieval_callback
165 
168  subroutine initialisation_callback(current_state)
169  type(model_state_type), target, intent(inout) :: current_state
170 
171  integer :: z_size, y_size, x_size
172 
173  z_size=current_state%local_grid%size(z_index) + current_state%local_grid%halo_size(z_index) * 2
174  y_size=current_state%local_grid%size(y_index) + current_state%local_grid%halo_size(y_index) * 2
175  x_size=current_state%local_grid%size(x_index) + current_state%local_grid%halo_size(x_index) * 2
176  allocate(current_state%vis_coefficient%data(z_size, y_size, x_size))
177 
178  z_size=current_state%global_grid%size(z_index)
179  allocate(u_viscosity(z_size), v_viscosity(z_size), w_viscosity(z_size))
180 
181  ! Tendency Logicals
182  l_tend_pr_tot_u = current_state%u%active
183  l_tend_pr_tot_v = current_state%v%active
184  l_tend_pr_tot_w = current_state%w%active
185 
186  l_tend_3d_u = current_state%u%active .or. l_tend_pr_tot_u
187  l_tend_3d_v = current_state%v%active .or. l_tend_pr_tot_v
188  l_tend_3d_w = current_state%w%active .or. l_tend_pr_tot_w
189 
190  ! Allocate 3d tendency fields upon availability
191  if (l_tend_3d_u) then
192  allocate( tend_3d_u(current_state%local_grid%size(z_index), &
193  current_state%local_grid%size(y_index), &
194  current_state%local_grid%size(x_index) ) )
195  endif
196  if (l_tend_3d_v) then
197  allocate( tend_3d_v(current_state%local_grid%size(z_index), &
198  current_state%local_grid%size(y_index), &
199  current_state%local_grid%size(x_index) ) )
200  endif
201  if (l_tend_3d_w) then
202  allocate( tend_3d_w(current_state%local_grid%size(z_index), &
203  current_state%local_grid%size(y_index), &
204  current_state%local_grid%size(x_index) ) )
205  endif
206 
207  ! Allocate profile tendency fields upon availability
208  if (l_tend_pr_tot_u) then
209  allocate( tend_pr_tot_u(current_state%local_grid%size(z_index)) )
210  endif
211  if (l_tend_pr_tot_v) then
212  allocate( tend_pr_tot_v(current_state%local_grid%size(z_index)) )
213  endif
214  if (l_tend_pr_tot_w) then
215  allocate( tend_pr_tot_w(current_state%local_grid%size(z_index)) )
216  endif
217 
218  ! Save the sampling_frequency to force diagnostic calculation on select time steps
219  diagnostic_generation_frequency=options_get_integer(current_state%options_database, "sampling_frequency")
220 
221  end subroutine initialisation_callback
222 
223  subroutine finalisation_callback(current_state)
224  type(model_state_type), target, intent(inout) :: current_state
225 
226  if (allocated(u_viscosity)) deallocate(u_viscosity)
227  if (allocated(v_viscosity)) deallocate(v_viscosity)
228  if (allocated(w_viscosity)) deallocate(w_viscosity)
229 
230  if (allocated(tend_3d_u)) deallocate(tend_3d_u)
231  if (allocated(tend_3d_v)) deallocate(tend_3d_v)
232  if (allocated(tend_3d_w)) deallocate(tend_3d_w)
233 
234  if (allocated(tend_pr_tot_u)) deallocate(tend_pr_tot_u)
235  if (allocated(tend_pr_tot_v)) deallocate(tend_pr_tot_v)
236  if (allocated(tend_pr_tot_w)) deallocate(tend_pr_tot_w)
237 
238  end subroutine finalisation_callback
239 
242  subroutine timestep_callback(current_state)
243  type(model_state_type), target, intent(inout) :: current_state
244 
245  integer :: local_y, locaL_x, k, target_x_index, target_y_index
246  real(kind=default_precision), dimension(current_state%local_grid%size(Z_INDEX)) :: tau12, tau12_ym1, tau12m1, &
247  tau11, tau22, tau22_yp1, tau33, tau23_ym1, tau11p1, tau13, tau13m1, tau23
248 
249  local_y=current_state%column_local_y
250  local_x=current_state%column_local_x
251  target_y_index=local_y-current_state%local_grid%halo_size(y_index)
252  target_x_index=local_x-current_state%local_grid%halo_size(x_index)
253 
254  ! Zero profile tendency totals on first instance in the sum
255  if (current_state%first_timestep_column) then
256  if (l_tend_pr_tot_u) then
257  tend_pr_tot_u(:)= 0.0_default_precision
258  endif
259  if (l_tend_pr_tot_v) then
260  tend_pr_tot_v(:)= 0.0_default_precision
261  endif
262  if (l_tend_pr_tot_w) then
263  tend_pr_tot_w(:)= 0.0_default_precision
264  endif
265  endif ! zero totals
266 
267  if (.not. current_state%use_viscosity_and_diffusion .or. current_state%halo_column) return
268 
269  if (current_state%viscosity_halo_swap_state%swap_in_progress) then
270  ! If there is a viscosity halo swap in progress then complete it
271  call complete_nonblocking_halo_swap(current_state, current_state%viscosity_halo_swap_state, &
273  end if
274 
275  if (mod(current_state%timestep, diagnostic_generation_frequency) == 0) then
276  call save_precomponent_tendencies(current_state, local_x, local_y, target_x_index, target_y_index)
277  end if
278 
279  if (current_state%field_stepping == forward_stepping) then
280  call calculate_tau(current_state, local_y, local_x, current_state%u, current_state%v, current_state%w, tau12, tau12_ym1, &
281  tau12m1, tau11, tau22, tau22_yp1, tau33, tau11p1, tau13, tau13m1, tau23, tau23_ym1)
282  else
283  call calculate_tau(current_state, local_y, local_x, current_state%zu, current_state%zv, current_state%zw, tau12, tau12_ym1, &
284  tau12m1, tau11, tau22, tau22_yp1, tau33, tau11p1, tau13, tau13m1, tau23, tau23_ym1)
285  end if
286  call calculate_viscous_sources(current_state, local_y, local_x, tau12, tau12_ym1, tau12m1, tau11, tau22, tau22_yp1, tau33, &
287  tau11p1, tau13, tau13m1, tau23, tau23_ym1)
288 
289  if (mod(current_state%timestep, diagnostic_generation_frequency) == 0) then
290  call compute_component_tendencies(current_state, local_x, local_y, target_x_index, target_y_index)
291  end if
292 
293  end subroutine timestep_callback
294 
299  subroutine calculate_viscous_sources(current_state, local_y, local_x, tau12, tau12_ym1, tau12m1, &
300  tau11, tau22, tau22_yp1, tau33, tau11p1, tau13, tau13m1, tau23, tau23_ym1)
301  type(model_state_type), target, intent(inout) :: current_state
302  integer, intent(in) :: local_y, local_x
303  real(kind=default_precision), dimension(:), intent(in) :: tau12, tau12_ym1, tau12m1, tau11, tau22, tau22_yp1, tau33, &
304  tau11p1, tau13, tau13m1, tau23, tau23_ym1
305 
306  integer :: k
307 
308  do k=2, current_state%local_grid%size(z_index)
309 #ifdef U_ACTIVE
310  u_viscosity(k)=((tau11p1(k)-tau11(k))*current_state%global_grid%configuration%horizontal%cx+(tau12(k)-tau12_ym1(k))*&
311  current_state%global_grid%configuration%horizontal%cy+(tau13(k)-tau13(k-1))*&
312  current_state%global_grid%configuration%vertical%rdz(k))/current_state%global_grid%configuration%vertical%rhon(k)
313  current_state%su%data(k, local_y, local_x)=current_state%su%data(k, local_y, local_x)+u_viscosity(k)
314 #endif
315 #ifdef V_ACTIVE
316  v_viscosity(k)=((tau12(k)-tau12m1(k))*current_state%global_grid%configuration%horizontal%cx+(tau22_yp1(k)-tau22(k))*&
317  current_state%global_grid%configuration%horizontal%cy+(tau23(k)-tau23(k-1))*&
318  current_state%global_grid%configuration%vertical%rdz(k))/current_state%global_grid%configuration%vertical%rhon(k)
319  current_state%sv%data(k, local_y, local_x)=current_state%sv%data(k, local_y, local_x)+v_viscosity(k)
320 #endif
321  end do
322 #ifdef W_ACTIVE
323  do k=2, current_state%local_grid%size(z_index)-1
324  w_viscosity(k)=((tau13(k)-tau13m1(k))*current_state%global_grid%configuration%horizontal%cx+(tau23(k)-tau23_ym1(k))*&
325  current_state%global_grid%configuration%horizontal%cy+(tau33(k+1)-tau33(k))*&
326  current_state%global_grid%configuration%vertical%rdzn(k+1))/current_state%global_grid%configuration%vertical%rho(k)
327  current_state%sw%data(k, local_y, local_x)=current_state%sw%data(k, local_y, local_x)+w_viscosity(k)
328  end do
329 #endif
330  end subroutine calculate_viscous_sources
331 
336  subroutine calculate_tau(current_state, local_y, local_x, zu, zv, zw, tau12, tau12_ym1, tau12m1, tau11, &
337  tau22, tau22_yp1, tau33, tau11p1, tau13, tau13m1, tau23, tau23_ym1)
338  type(model_state_type), target, intent(inout) :: current_state
339  type(prognostic_field_type), intent(inout) :: zu, zv, zw
340  integer, intent(in) :: local_y, local_x
341  real(kind=default_precision), dimension(:), intent(out) :: tau12, tau12m1, tau11, tau22, tau22_yp1, tau33, &
342  tau11p1, tau13, tau13m1, tau23, tau23_ym1, tau12_ym1
343 
344  integer :: k
345  real(kind=default_precision) :: vistmp, vis12, vis12a, visonp2, visonp2a, vis13, vis23
346 
347  ! Do p levels and w-levels
348  do k=1, current_state%local_grid%size(z_index)
349  if (k .gt. 1) then
350  vistmp=current_state%vis_coefficient%data(k, local_y, local_x)+current_state%vis_coefficient%data(k, local_y+1, local_x)+&
351  current_state%vis_coefficient%data(k-1, local_y, local_x)+current_state%vis_coefficient%data(k-1, local_y+1, local_x)
352  vis12=0.125_default_precision*(vistmp + current_state%vis_coefficient%data(k, local_y, local_x+1)+&
353  current_state%vis_coefficient%data(k, local_y+1, local_x+1)+&
354  current_state%vis_coefficient%data(k-1, local_y, local_x+1)+&
355  current_state%vis_coefficient%data(k-1, local_y+1, local_x+1))
356  tau12(k)=0.0_default_precision
357 #ifdef U_ACTIVE
358  tau12(k)=(zu%data(k, local_y+1, local_x)-zu%data(k, local_y, local_x))*&
359  current_state%global_grid%configuration%horizontal%cy
360 #endif
361 #ifdef V_ACTIVE
362  tau12(k)=tau12(k)+(zv%data(k, local_y, local_x+1)-zv%data(k, local_y, local_x))*&
363  current_state%global_grid%configuration%horizontal%cx
364 #endif
365  tau12(k)=tau12(k)*current_state%global_grid%configuration%vertical%rhon(k)*vis12
366 
367  vis12a=0.125_default_precision*(vistmp +current_state%vis_coefficient%data(k, local_y, local_x-1)+&
368  current_state%vis_coefficient%data(k, local_y+1, local_x-1)+&
369  current_state%vis_coefficient%data(k-1, local_y, local_x-1)+&
370  current_state%vis_coefficient%data(k-1, local_y+1, local_x-1))
371  tau12m1(k)=0.0_default_precision
372 #ifdef U_ACTIVE
373  tau12m1(k)=(zu%data(k, local_y+1, local_x-1)-zu%data(k, local_y, local_x-1))*&
374  current_state%global_grid%configuration%horizontal%cy
375 #endif
376 #ifdef V_ACTIVE
377  tau12m1(k)=tau12m1(k)+(zv%data(k, local_y, local_x)-zv%data(k, local_y, local_x-1))*&
378  current_state%global_grid%configuration%horizontal%cx
379 #endif
380  tau12m1(k)=tau12m1(k)*current_state%global_grid%configuration%vertical%rhon(k)*vis12a
381 
382  vistmp=current_state%vis_coefficient%data(k, local_y-1, local_x)+current_state%vis_coefficient%data(k, local_y, local_x)+&
383  current_state%vis_coefficient%data(k-1, local_y-1, local_x)+current_state%vis_coefficient%data(k-1, local_y, local_x)
384  vis12=0.125_default_precision*(vistmp + current_state%vis_coefficient%data(k, local_y-1, local_x+1)+&
385  current_state%vis_coefficient%data(k, local_y, local_x+1)+&
386  current_state%vis_coefficient%data(k-1, local_y-1, local_x+1)+&
387  current_state%vis_coefficient%data(k-1, local_y, local_x+1))
388  tau12_ym1(k)=0.0_default_precision
389 #ifdef U_ACTIVE
390  tau12_ym1(k)=(zu%data(k, local_y, local_x)-zu%data(k, local_y-1, local_x))*&
391  current_state%global_grid%configuration%horizontal%cy
392 #endif
393 #ifdef V_ACTIVE
394  tau12_ym1(k)=tau12_ym1(k)+(zv%data(k, local_y-1, local_x+1)-zv%data(k, local_y-1, local_x))*&
395  current_state%global_grid%configuration%horizontal%cx
396 #endif
397  tau12_ym1(k)=tau12_ym1(k)*current_state%global_grid%configuration%vertical%rhon(k)*vis12
398 
399  visonp2=current_state%global_grid%configuration%vertical%rhon(k)*&
400  (current_state%vis_coefficient%data(k, local_y, local_x)+current_state%vis_coefficient%data(k-1, local_y, local_x))
401 #ifdef U_ACTIVE
402  tau11(k)=visonp2*(zu%data(k, local_y, local_x)-zu%data(k, local_y, local_x-1))*&
403  current_state%global_grid%configuration%horizontal%cx
404 #else
405  tau11(k)=0.0_default_precision
406 #endif
407 #ifdef V_ACTIVE
408  tau22(k)=visonp2*(zv%data(k, local_y, local_x)-zv%data(k, local_y-1, local_x))*&
409  current_state%global_grid%configuration%horizontal%cy
410 #else
411  tau22(k)=0.0_default_precision
412 #endif
413 #ifdef W_ACTIVE
414  tau33(k)=visonp2*(zw%data(k, local_y, local_x)-zw%data(k-1, local_y, local_x))*&
415  current_state%global_grid%configuration%vertical%rdz(k)
416 #else
417  tau33(k)=0.0_default_precision
418 #endif
419 
420 #ifdef V_ACTIVE
421  visonp2=current_state%global_grid%configuration%vertical%rhon(k)*&
422  (current_state%vis_coefficient%data(k, local_y+1, local_x)+&
423  current_state%vis_coefficient%data(k-1, local_y+1, local_x))
424  tau22_yp1(k)=visonp2*(zv%data(k, local_y+1, local_x)-zv%data(k, local_y, local_x))*&
425  current_state%global_grid%configuration%horizontal%cy
426 #endif
427 
428 #ifdef U_ACTIVE
429  visonp2a=current_state%global_grid%configuration%vertical%rhon(k)*&
430  (current_state%vis_coefficient%data(k, local_y, local_x+1)+&
431  current_state%vis_coefficient%data(k-1, local_y, local_x+1))
432  tau11p1(k)=visonp2a*(current_state%zu%data(k, local_y, local_x+1)-&
433  zu%data(k, local_y, local_x))*current_state%global_grid%configuration%horizontal%cx
434 #endif
435  else
436  tau12(k)=0.0_default_precision
437  tau12_ym1(k)=0.0_default_precision
438  tau12m1(k)=0.0_default_precision
439  tau11(k)=0.0_default_precision
440  tau22(k)=0.0_default_precision
441  tau22_yp1(k)=0.0_default_precision
442  tau33(k)=0.0_default_precision
443  tau11p1(k)=0.0_default_precision
444  end if
445  if (k .lt. current_state%local_grid%size(z_index)) then
446  vis13=0.5_default_precision*(current_state%vis_coefficient%data(k, local_y, local_x)+&
447  current_state%vis_coefficient%data(k, local_y, local_x+1))
448  tau13(k)=0.0_default_precision
449 #ifdef U_ACTIVE
450  tau13(k)=(zu%data(k+1, local_y, local_x)-zu%data(k, local_y, local_x))*&
451  current_state%global_grid%configuration%vertical%rdzn(k+1)
452 #endif
453 #ifdef W_ACTIVE
454  tau13(k)=tau13(k)+(zw%data(k, local_y, local_x+1)-zw%data(k, local_y, local_x))*&
455  current_state%global_grid%configuration%horizontal%cx
456 #endif
457  tau13(k)=tau13(k)*current_state%global_grid%configuration%vertical%rho(k)*vis13
458 
459  vis13=0.5_default_precision*(current_state%vis_coefficient%data(k, local_y, local_x-1)+&
460  current_state%vis_coefficient%data(k, local_y, local_x))
461  tau13m1(k)=0.0_default_precision
462 #ifdef U_ACTIVE
463  tau13m1(k)=(zu%data(k+1, local_y, local_x-1)-zu%data(k, local_y, local_x-1))*&
464  current_state%global_grid%configuration%vertical%rdzn(k+1)
465 #endif
466 #ifdef W_ACTIVE
467  tau13m1(k)=tau13m1(k)+(zw%data(k, local_y, local_x)-zw%data(k, local_y, local_x-1))*&
468  current_state%global_grid%configuration%horizontal%cx
469 #endif
470  tau13m1(k)=tau13m1(k)*current_state%global_grid%configuration%vertical%rho(k)*vis13
471 
472  vis23=0.5_default_precision*(current_state%vis_coefficient%data(k, local_y, local_x)+&
473  current_state%vis_coefficient%data(k, local_y+1, local_x))
474  tau23(k)=0.0_default_precision
475 #ifdef W_ACTIVE
476  tau23(k)=(zw%data(k, local_y+1, local_x)-zw%data(k, local_y, local_x))*&
477  current_state%global_grid%configuration%horizontal%cy
478 #endif
479 #ifdef V_ACTIVE
480  tau23(k)=tau23(k)+(zv%data(k+1, local_y, local_x)-zv%data(k, local_y, local_x))*&
481  current_state%global_grid%configuration%vertical%rdzn(k+1)
482 #endif
483  tau23(k)=tau23(k)*current_state%global_grid%configuration%vertical%rho(k)*vis23
484 
485  vis23=0.5_default_precision*(current_state%vis_coefficient%data(k, local_y-1, local_x)+&
486  current_state%vis_coefficient%data(k, local_y, local_x))
487  tau23_ym1(k)=0.0_default_precision
488 #ifdef W_ACTIVE
489  tau23_ym1(k)=(zw%data(k, local_y, local_x)-zw%data(k, local_y-1, local_x))*&
490  current_state%global_grid%configuration%horizontal%cy
491 #endif
492 #ifdef V_ACTIVE
493  tau23_ym1(k)=tau23_ym1(k)+(zv%data(k+1, local_y-1, local_x)-zv%data(k, local_y-1, local_x))*&
494  current_state%global_grid%configuration%vertical%rdzn(k+1)
495 #endif
496  tau23_ym1(k)=tau23_ym1(k)*current_state%global_grid%configuration%vertical%rho(k)*vis23
497  else
498  tau13(k)=0.0_default_precision
499  tau13m1(k)=0.0_default_precision
500  tau23(k)=0.0_default_precision
501  tau23_ym1(k)=0.0_default_precision
502  end if
503  end do
504  end subroutine calculate_tau
505 
509  subroutine perform_local_data_copy_for_vis(current_state, halo_depth, involve_corners, source_data)
510  type(model_state_type), intent(inout) :: current_state
511  integer, intent(in) :: halo_depth
512  logical, intent(in) :: involve_corners
513  type(field_data_wrapper_type), dimension(:), intent(in), optional :: source_data
514 
515  call perform_local_data_copy_for_field(current_state%vis_coefficient%data, current_state%local_grid, &
516  current_state%parallel%my_rank, halo_depth, involve_corners)
517  end subroutine perform_local_data_copy_for_vis
518 
527  subroutine copy_halo_buffer_to_vis(current_state, neighbour_description, dim, target_index, &
528  neighbour_location, current_page, source_data)
529  type(model_state_type), intent(inout) :: current_state
530  integer, intent(in) :: dim, target_index, neighbour_location
531  integer, intent(inout) :: current_page(:)
532  type(neighbour_description_type), intent(inout) :: neighbour_description
533  type(field_data_wrapper_type), dimension(:), intent(in), optional :: source_data
534 
535  call copy_buffer_to_field(current_state%local_grid, neighbour_description%recv_halo_buffer, &
536  current_state%vis_coefficient%data, dim, target_index, current_page(neighbour_location))
537 
538  current_page(neighbour_location)=current_page(neighbour_location)+1
539  end subroutine copy_halo_buffer_to_vis
540 
550  subroutine copy_halo_buffer_to_vis_corners(current_state, neighbour_description, corner_loc, x_target_index, &
551  y_target_index, neighbour_location, current_page, source_data)
552  type(model_state_type), intent(inout) :: current_state
553  integer, intent(in) :: corner_loc, x_target_index, y_target_index, neighbour_location
554  integer, intent(inout) :: current_page(:)
555  type(neighbour_description_type), intent(inout) :: neighbour_description
556  type(field_data_wrapper_type), dimension(:), intent(in), optional :: source_data
557 
558  call copy_buffer_to_corner(current_state%local_grid, neighbour_description%recv_corner_buffer, &
559  current_state%vis_coefficient%data, corner_loc, x_target_index, y_target_index, current_page(neighbour_location))
560 
561  current_page(neighbour_location)=current_page(neighbour_location)+1
562  end subroutine copy_halo_buffer_to_vis_corners
563 
570  subroutine save_precomponent_tendencies(current_state, cxn, cyn, txn, tyn)
571  type(model_state_type), target, intent(in) :: current_state
572  integer, intent(in) :: cxn, cyn, txn, tyn
573 
574  ! Save 3d tendency fields upon request (of 3d or profiles) and availability
575  if (l_tend_3d_u) then
576  tend_3d_u(:,tyn,txn)=current_state%su%data(:,cyn,cxn)
577  endif
578  if (l_tend_3d_v) then
579  tend_3d_v(:,tyn,txn)=current_state%sv%data(:,cyn,cxn)
580  endif
581  if (l_tend_3d_w) then
582  tend_3d_w(:,tyn,txn)=current_state%sw%data(:,cyn,cxn)
583  endif
584 
585  end subroutine save_precomponent_tendencies
586 
587 
594  subroutine compute_component_tendencies(current_state, cxn, cyn, txn, tyn)
595  type(model_state_type), target, intent(inout) :: current_state
596  integer, intent(in) :: cxn, cyn, txn, tyn
597 
598  ! Calculate change in tendency due to component
599  if (l_tend_3d_u) then
600  tend_3d_u(:,tyn,txn)=current_state%su%data(:,cyn,cxn) - tend_3d_u(:,tyn,txn)
601  endif
602  if (l_tend_3d_v) then
603  tend_3d_v(:,tyn,txn)=current_state%sv%data(:,cyn,cxn) - tend_3d_v(:,tyn,txn)
604  endif
605  if (l_tend_3d_w) then
606  tend_3d_w(:,tyn,txn)=current_state%sw%data(:,cyn,cxn) - tend_3d_w(:,tyn,txn)
607  endif
608 
609  ! Add local tendency fields to the profile total
610  if (l_tend_pr_tot_u) then
611  tend_pr_tot_u(:)=tend_pr_tot_u(:) + tend_3d_u(:,tyn,txn)
612  endif
613  if (l_tend_pr_tot_v) then
614  tend_pr_tot_v(:)=tend_pr_tot_v(:) + tend_3d_v(:,tyn,txn)
615  endif
616  if (l_tend_pr_tot_w) then
617  tend_pr_tot_w(:)=tend_pr_tot_w(:) + tend_3d_w(:,tyn,txn)
618  endif
619 
620  end subroutine compute_component_tendencies
621 
622 
627  subroutine set_published_field_value(field_value, real_1d_field, real_2d_field, real_3d_field)
628  type(component_field_value_type), intent(inout) :: field_value
629  real(kind=default_precision), dimension(:), optional :: real_1d_field
630  real(kind=default_precision), dimension(:,:), optional :: real_2d_field
631  real(kind=default_precision), dimension(:,:,:), optional :: real_3d_field
632 
633  if (present(real_1d_field)) then
634  allocate(field_value%real_1d_array(size(real_1d_field)), source=real_1d_field)
635  else if (present(real_2d_field)) then
636  allocate(field_value%real_2d_array(size(real_2d_field, 1), size(real_2d_field, 2)), source=real_2d_field)
637  else if (present(real_3d_field)) then
638  allocate(field_value%real_3d_array(size(real_3d_field, 1), size(real_3d_field, 2), size(real_3d_field, 3)), &
639  source=real_3d_field)
640  end if
641  end subroutine set_published_field_value
642 
643 end module viscosity_mod
registry_mod::is_component_enabled
logical function, public is_component_enabled(options_database, component_name)
Determines whether or not a specific component is registered and enabled.
Definition: registry.F90:334
logging_mod::log_error
integer, parameter, public log_error
Only log ERROR messages.
Definition: logging.F90:11
viscosity_mod::tend_3d_v
real(kind=default_precision), dimension(:,:,:), allocatable tend_3d_v
Definition: viscosity.F90:27
viscosity_mod
Computes the viscosity dynamics for the U,V,W source terms.
Definition: viscosity.F90:2
communication_types_mod::neighbour_description_type
Describes the neighbours of a process in a specific dimension and contains the communication buffers ...
Definition: communicationtypes.F90:20
prognostics_mod
Contains prognostic field definitions and functions.
Definition: prognostics.F90:2
logging_mod::log_warn
integer, parameter, public log_warn
Log WARNING and ERROR messages.
Definition: logging.F90:12
viscosity_mod::w_viscosity
real(kind=default_precision), dimension(:), allocatable w_viscosity
Definition: viscosity.F90:23
halo_communication_mod
Provides the mechanism for halo swapping. This module contains the functionality required to determin...
Definition: halocommunication.F90:8
viscosity_mod::calculate_tau
subroutine calculate_tau(current_state, local_y, local_x, zu, zv, zw, tau12, tau12_ym1, tau12m1, tau11, tau22, tau22_yp1, tau33, tau11p1, tau13, tau13m1, tau23, tau23_ym1)
Calculated TAU which is used in computing the viscous source terms.
Definition: viscosity.F90:338
viscosity_mod::timestep_callback
subroutine timestep_callback(current_state)
At each timestep will compute the viscosity U,V,W source terms.
Definition: viscosity.F90:243
viscosity_mod::copy_halo_buffer_to_vis
subroutine copy_halo_buffer_to_vis(current_state, neighbour_description, dim, target_index, neighbour_location, current_page, source_data)
Copies the halo buffer to halo location for the viscosity coefficient field.
Definition: viscosity.F90:529
grids_mod::x_index
integer, parameter, public x_index
Definition: grids.F90:14
optionsdatabase_mod::options_get_integer
integer function, public options_get_integer(options_database, key, index)
Retrieves an integer value from the database that matches the provided key.
Definition: optionsdatabase.F90:217
viscosity_mod::save_precomponent_tendencies
subroutine save_precomponent_tendencies(current_state, cxn, cyn, txn, tyn)
Save the 3d tendencies coming into the component.
Definition: viscosity.F90:571
grids_mod::y_index
integer, parameter, public y_index
Definition: grids.F90:14
viscosity_mod::compute_component_tendencies
subroutine compute_component_tendencies(current_state, cxn, cyn, txn, tyn)
Computation of component tendencies.
Definition: viscosity.F90:595
viscosity_mod::l_tend_3d_u
logical l_tend_3d_u
Definition: viscosity.F90:29
viscosity_mod::calculate_viscous_sources
subroutine calculate_viscous_sources(current_state, local_y, local_x, tau12, tau12_ym1, tau12m1, tau11, tau22, tau22_yp1, tau33, tau11p1, tau13, tau13m1, tau23, tau23_ym1)
Calculates the viscous sources based upon TAU for the U,V and W fields.
Definition: viscosity.F90:301
viscosity_mod::finalisation_callback
subroutine finalisation_callback(current_state)
Definition: viscosity.F90:224
viscosity_mod::perform_local_data_copy_for_vis
subroutine perform_local_data_copy_for_vis(current_state, halo_depth, involve_corners, source_data)
Does local data copying for viscosity coefficient variable halo swap.
Definition: viscosity.F90:510
communication_types_mod
Contains the types used for communication, holding the state of communications and supporting activit...
Definition: communicationtypes.F90:5
viscosity_mod::initialisation_callback
subroutine initialisation_callback(current_state)
Sets up the stencil_mod (used in interpolation) and allocates data for the flux fields.
Definition: viscosity.F90:169
viscosity_mod::u_viscosity
real(kind=default_precision), dimension(:), allocatable u_viscosity
Definition: viscosity.F90:23
communication_types_mod::halo_communication_type
Maintains the state of a halo swap and contains buffers, neighbours etc.
Definition: communicationtypes.F90:28
monc_component_mod
Interfaces and types that MONC components must specify.
Definition: monc_component.F90:6
viscosity_mod::field_value_retrieval_callback
subroutine field_value_retrieval_callback(current_state, name, field_value)
Field value retrieval callback, this returns the value of a specific published field.
Definition: viscosity.F90:135
communication_types_mod::field_data_wrapper_type
Definition: communicationtypes.F90:14
viscosity_mod::diagnostic_generation_frequency
integer diagnostic_generation_frequency
Definition: viscosity.F90:35
viscosity_mod::field_information_retrieval_callback
subroutine field_information_retrieval_callback(current_state, name, field_information)
Field information retrieval callback, this returns information for a specific components published fi...
Definition: viscosity.F90:73
halo_communication_mod::complete_nonblocking_halo_swap
subroutine, public complete_nonblocking_halo_swap(current_state, halo_swap_state, perform_local_data_copy, copy_from_halo_buffer, copy_from_halo_buffer_to_corner, source_data)
This completes a nonblocking halo swap and it is only during this call that the data fields themselve...
Definition: halocommunication.F90:182
viscosity_mod::tend_3d_u
real(kind=default_precision), dimension(:,:,:), allocatable tend_3d_u
Definition: viscosity.F90:27
viscosity_mod::l_tend_pr_tot_w
logical l_tend_pr_tot_w
Definition: viscosity.F90:33
halo_communication_mod::copy_buffer_to_corner
subroutine, public copy_buffer_to_corner(local_grid, halo_buffer, field_data, corner_loc, x_target_index, y_target_index, halo_page)
Copies the received buffer for a specific field to the corresponding corner of that field.
Definition: halocommunication.F90:368
viscosity_mod::viscosity_get_descriptor
type(component_descriptor_type) function, public viscosity_get_descriptor()
Provides the descriptor back to the caller and is used in component registration.
Definition: viscosity.F90:44
grids_mod::z_index
integer, parameter, public z_index
Grid index parameters.
Definition: grids.F90:14
viscosity_mod::copy_halo_buffer_to_vis_corners
subroutine copy_halo_buffer_to_vis_corners(current_state, neighbour_description, corner_loc, x_target_index, y_target_index, neighbour_location, current_page, source_data)
Copies the corner halo buffer to the viscosity coefficient field corners.
Definition: viscosity.F90:552
viscosity_mod::l_tend_3d_w
logical l_tend_3d_w
Definition: viscosity.F90:29
monc_component_mod::component_field_value_type
Wrapper type for the value returned for a published field from a component.
Definition: monc_component.F90:22
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
monc_component_mod::component_field_information_type
Definition: monc_component.F90:31
viscosity_mod::tend_pr_tot_w
real(kind=default_precision), dimension(:), allocatable tend_pr_tot_w
Definition: viscosity.F90:31
halo_communication_mod::copy_buffer_to_field
subroutine, public copy_buffer_to_field(local_grid, halo_buffer, field_data, dim, target_index, halo_page)
Copies the received buffer for a specific field to the corresponding halo data of that prognostic fie...
Definition: halocommunication.F90:401
viscosity_mod::tend_3d_w
real(kind=default_precision), dimension(:,:,:), allocatable tend_3d_w
Definition: viscosity.F90:27
logging_mod
Logging utility.
Definition: logging.F90:2
prognostics_mod::prognostic_field_type
A prognostic field which is assumed to be 3D.
Definition: prognostics.F90:13
datadefn_mod
Contains common definitions for the data and datatypes used by MONC.
Definition: datadefn.F90:2
viscosity_mod::l_tend_pr_tot_u
logical l_tend_pr_tot_u
Definition: viscosity.F90:33
logging_mod::log_master_log
subroutine, public log_master_log(level, message)
Will log just from the master process.
Definition: logging.F90:47
registry_mod
MONC component registry.
Definition: registry.F90:5
viscosity_mod::set_published_field_value
subroutine set_published_field_value(field_value, real_1d_field, real_2d_field, real_3d_field)
Sets the published field value from the temporary diagnostic values held by this component.
Definition: viscosity.F90:628
viscosity_mod::l_tend_3d_v
logical l_tend_3d_v
Definition: viscosity.F90:29
viscosity_mod::tend_pr_tot_u
real(kind=default_precision), dimension(:), allocatable tend_pr_tot_u
Definition: viscosity.F90:31
viscosity_mod::l_tend_pr_tot_v
logical l_tend_pr_tot_v
Definition: viscosity.F90:33
grids_mod
Functionality to support the different types of grid and abstraction between global grids and local o...
Definition: grids.F90:5
viscosity_mod::tend_pr_tot_v
real(kind=default_precision), dimension(:), allocatable tend_pr_tot_v
Definition: viscosity.F90:31
optionsdatabase_mod
Manages the options database. Contains administration functions and deduce runtime options from the c...
Definition: optionsdatabase.F90:7
viscosity_mod::v_viscosity
real(kind=default_precision), dimension(:), allocatable v_viscosity
Definition: viscosity.F90:23
monc_component_mod::component_descriptor_type
Description of a component.
Definition: monc_component.F90:42
monc_component_mod::component_double_data_type
integer, parameter, public component_double_data_type
Definition: monc_component.F90:16
halo_communication_mod::perform_local_data_copy_for_field
subroutine, public perform_local_data_copy_for_field(field_data, local_grid, my_rank, halo_depth, involve_corners)
Will perform a a local copy for the halo data of a field.
Definition: halocommunication.F90:483
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
monc_component_mod::component_array_field_type
integer, parameter, public component_array_field_type
Definition: monc_component.F90:15