15 use mpi
, only: mpi_request_null, mpi_statuses_ignore
24 real(kind=DEFAULT_PRECISION),
parameter ::
smth = 0.05_default_precision,&
25 tolm=1.0e-4_default_precision,
tolt=1.0e-4_default_precision
50 type(model_state_type),
target,
intent(inout) :: current_state
52 real(kind=DEFAULT_PRECISION) :: bhbc
53 integer :: num_wrapped_fields
57 if (.not. is_component_enabled(current_state%options_database,
"diffusion"))
then 58 call log_master_log(log_error,
"Lowerbc requires the diffusion component to be enabled")
60 if (.not. is_component_enabled(current_state%options_database,
"viscosity"))
then 61 call log_master_log(log_error,
"Lowerbc requires the viscosity component to be enabled")
69 if (current_state%th%active) num_wrapped_fields=1
70 num_wrapped_fields=num_wrapped_fields+current_state%number_q_fields
72 if (num_wrapped_fields .gt. 0)
then 73 if (current_state%parallel%my_coords(y_index) == 0 .or. &
74 current_state%parallel%my_coords(y_index) == current_state%parallel%dim_sizes(y_index)-1)
then 75 if (current_state%parallel%my_coords(y_index) == 0)
then 86 if (current_state%parallel%my_coords(x_index) == 0 .or. &
87 current_state%parallel%my_coords(x_index) == current_state%parallel%dim_sizes(x_index)-1)
then 88 if (current_state%parallel%my_coords(x_index) == 0)
then 101 1.0_default_precision/(current_state%global_grid%configuration%horizontal%dx*&
102 current_state%global_grid%configuration%horizontal%dx)+&
103 1.0_default_precision/(current_state%global_grid%configuration%horizontal%dy*&
104 current_state%global_grid%configuration%horizontal%dy)
106 if ( current_state%use_surface_boundary_conditions .and. &
107 current_state%type_of_surface_boundary_conditions == prescribed_surface_values)
then 109 tstrcona=von_karman_constant/alphah*current_state%global_grid%configuration%vertical%zlogth
110 bhbc=alphah*current_state%global_grid%configuration%vertical%zlogth
111 rhmbc=betah*(current_state%global_grid%configuration%vertical%zn(2)+z0-z0th)/&
112 (betam*current_state%global_grid%configuration%vertical%zn(2))
113 ddbc=current_state%global_grid%configuration%vertical%zlogm*(bhbc-&
114 rhmbc*current_state%global_grid%configuration%vertical%zlogm)
117 eecon=2.0_default_precision*
rhmbc*current_state%global_grid%configuration%vertical%zlogm-bhbc
118 rcmbc=1.0_default_precision/current_state%cmbc
120 x4con=gammam*(current_state%global_grid%configuration%vertical%zn(2)+z0)
122 y2con=gammah*(current_state%global_grid%configuration%vertical%zn(2)+z0)
141 if (.not. current_state%passive_q)
then 142 iqv = get_q_index(standard_q_names%VAPOUR,
'lowerbc')
148 type(model_state_type),
target,
intent(inout) :: current_state
157 type(model_state_type),
target,
intent(inout) :: current_state
159 integer :: z_size, y_size, x_size, i
161 z_size=current_state%local_grid%size(z_index) + current_state%local_grid%halo_size(z_index) * 2
162 y_size=current_state%local_grid%size(y_index) + current_state%local_grid%halo_size(y_index) * 2
163 x_size=current_state%local_grid%size(x_index) + current_state%local_grid%halo_size(x_index) * 2
165 allocate(current_state%dis%data(z_size, y_size, x_size), &
166 current_state%dis_th%data(z_size, y_size, x_size), current_state%disq(current_state%number_q_fields))
168 do i=1,current_state%number_q_fields
169 allocate(current_state%disq(i)%data(z_size, y_size, x_size))
174 type(model_state_type),
target,
intent(inout) :: current_state
176 integer :: current_y_index, current_x_index
178 current_y_index=current_state%column_local_y
179 current_x_index=current_state%column_local_x
181 if (current_state%field_stepping == forward_stepping)
then 183 current_state%u, current_state%v, current_state%th, current_state%th, current_state%q, current_state%q)
185 if (current_state%scalar_stepping == forward_stepping)
then 187 current_state%zu, current_state%zv, current_state%th, current_state%zth, current_state%q, current_state%zq)
190 current_state%zu, current_state%zv, current_state%zth, current_state%zth, current_state%zq, current_state%zq)
196 type(model_state_type),
target,
intent(inout) :: current_state
197 type(prognostic_field_type),
intent(inout) :: zu, zv, th, zth
198 type(prognostic_field_type),
dimension(:),
intent(inout) :: q, zq
199 integer,
intent(in) :: current_y_index, current_x_index
202 real(kind=DEFAULT_PRECISION) :: horizontal_velocity_at_k2
204 if (.not. current_state%use_viscosity_and_diffusion .or. .not. current_state%use_surface_boundary_conditions)
then 208 if (.not. (current_state%column_local_y .lt. current_state%local_grid%local_domain_start_index(y_index)-1 .or.&
209 current_state%column_local_x .lt. current_state%local_grid%local_domain_start_index(x_index)-1 .or.&
210 current_state%column_local_y .gt. current_state%local_grid%local_domain_end_index(y_index)+1 .or.&
211 current_state%column_local_x .gt. current_state%local_grid%local_domain_end_index(x_index)+1))
then 216 horizontal_velocity_at_k2=0.0_default_precision
218 horizontal_velocity_at_k2=(0.5_default_precision*(current_state%zu%data(2,current_y_index,current_x_index)+&
219 zu%data(2,current_y_index,current_x_index-1))+ current_state%ugal)**2
222 horizontal_velocity_at_k2=horizontal_velocity_at_k2+(0.5_default_precision*(zv%data(&
223 2,current_y_index,current_x_index)+zv%data(2,current_y_index-1,current_x_index))+current_state%vgal)**2
225 horizontal_velocity_at_k2=sqrt(horizontal_velocity_at_k2)+smallp
227 if (current_state%type_of_surface_boundary_conditions == prescribed_surface_fluxes)
then 229 horizontal_velocity_at_k2, th, q)
232 horizontal_velocity_at_k2, zth, th, zq, q)
235 current_state%dis%data(1, current_y_index, current_x_index)=0.0_default_precision
236 current_state%dis_th%data(1, current_y_index, current_x_index)=0.0_default_precision
238 if (current_state%backscatter)
then 239 do n=1, current_state%number_q_fields
240 current_state%disq(n)%data(1,current_y_index,current_x_index)=0.0_default_precision
248 current_state%cvis=max(current_state%cvis,max(current_state%vis_coefficient%data(1, current_y_index, current_x_index),&
251 else if (current_x_index == 1 .and. current_y_index == 1)
then 253 else if (current_x_index == current_state%local_grid%local_domain_end_index(x_index)+&
254 current_state%local_grid%halo_size(x_index) .and. current_y_index == &
255 current_state%local_grid%local_domain_end_index(y_index)+current_state%local_grid%halo_size(y_index))
then 264 type(model_state_type),
target,
intent(inout) :: current_state
283 type(model_state_type),
target,
intent(inout) :: current_state
284 type(prognostic_field_type),
intent(inout) :: zth
285 type(prognostic_field_type),
dimension(:),
intent(inout) :: zq
291 if (current_state%parallel%my_coords(y_index) == 0)
then 293 current_state%local_grid%local_domain_start_index(y_index)+1)
296 current_state%local_grid%local_domain_end_index(y_index))
303 if (current_state%parallel%my_coords(x_index) == 0)
then 305 current_state%local_grid%local_domain_start_index(x_index)+1)
308 current_state%local_grid%local_domain_end_index(x_index))
319 if (current_state%parallel%my_coords(y_index) == 0)
then 323 current_state%local_grid%local_domain_end_index(y_index)+1, &
324 current_state%local_grid%local_domain_end_index(y_index)+2)
328 if (current_state%parallel%my_coords(x_index) == 0)
then 332 current_state%local_grid%local_domain_end_index(x_index)+1, &
333 current_state%local_grid%local_domain_end_index(x_index)+2)
338 if (current_state%th%active)
then 339 zth%data(1,1,:)=zth%data(1, current_state%local_grid%local_domain_end_index(y_index)-1, :)
340 zth%data(1,2,:)=zth%data(1, current_state%local_grid%local_domain_end_index(y_index), :)
341 zth%data(1,current_state%local_grid%local_domain_end_index(y_index)+1,:)=&
342 zth%data(1, current_state%local_grid%local_domain_start_index(y_index), :)
343 zth%data(1,current_state%local_grid%local_domain_end_index(y_index)+2,:)=&
344 zth%data(1, current_state%local_grid%local_domain_start_index(y_index)+1, :)
346 if (current_state%number_q_fields .gt. 0)
then 347 do n=1, current_state%number_q_fields
348 zq(n)%data(1,1,:)=zq(n)%data(1, current_state%local_grid%local_domain_end_index(y_index)-1, :)
349 zq(n)%data(1,2,:)=zq(n)%data(1, current_state%local_grid%local_domain_end_index(y_index), :)
350 zq(n)%data(1,current_state%local_grid%local_domain_end_index(y_index)+1,:)=&
351 zq(n)%data(1, current_state%local_grid%local_domain_start_index(y_index), :)
352 zq(n)%data(1,current_state%local_grid%local_domain_end_index(y_index)+2,:)=&
353 zq(n)%data(1, current_state%local_grid%local_domain_start_index(y_index)+1, :)
359 if (current_state%th%active)
then 360 zth%data(1,:,1)=zth%data(1,:,current_state%local_grid%local_domain_end_index(x_index)-1)
361 zth%data(1,:,2)=zth%data(1,:,current_state%local_grid%local_domain_end_index(x_index))
362 zth%data(1,:,current_state%local_grid%local_domain_end_index(x_index)+1)=&
363 zth%data(1,:,current_state%local_grid%local_domain_start_index(x_index))
364 zth%data(1,:,current_state%local_grid%local_domain_end_index(x_index)+2)=&
365 zth%data(1,:,current_state%local_grid%local_domain_start_index(x_index)+1)
367 if (current_state%number_q_fields .gt. 0)
then 368 do n=1, current_state%number_q_fields
369 zq(n)%data(1,:,1)=zq(n)%data(1,:,current_state%local_grid%local_domain_end_index(x_index)-1)
370 zq(n)%data(1,:,2)=zq(n)%data(1,:,current_state%local_grid%local_domain_end_index(x_index))
371 zq(n)%data(1,:,current_state%local_grid%local_domain_end_index(x_index)+1)=&
372 zq(n)%data(1,:,current_state%local_grid%local_domain_start_index(x_index))
373 zq(n)%data(1,:,current_state%local_grid%local_domain_end_index(x_index)+2)=&
374 zq(n)%data(1,:,current_state%local_grid%local_domain_start_index(x_index)+1)
387 type(model_state_type),
target,
intent(inout) :: current_state
388 type(prognostic_field_type),
intent(inout) :: zth
389 type(prognostic_field_type),
dimension(:),
intent(inout) :: zq
390 integer,
intent(in) :: first_y_index, second_y_index
392 integer :: index_start, n
395 if (current_state%th%active)
then 398 index_start=index_start+1
400 if (current_state%number_q_fields .gt. 0)
then 401 do n=1, current_state%number_q_fields
415 type(model_state_type),
target,
intent(inout) :: current_state
416 type(prognostic_field_type),
intent(inout) :: zth
417 type(prognostic_field_type),
dimension(:),
intent(inout) :: zq
418 integer,
intent(in) :: first_x_index, second_x_index
420 integer :: index_start, n
423 if (current_state%th%active)
then 426 index_start=index_start+1
428 if (current_state%number_q_fields .gt. 0)
then 429 do n=1, current_state%number_q_fields
443 type(model_state_type),
target,
intent(inout) :: current_state
444 type(prognostic_field_type),
intent(inout) :: zth
445 type(prognostic_field_type),
dimension(:),
intent(inout) :: zq
446 integer,
intent(in) :: first_y_index, second_y_index
448 integer :: index_start, n
451 if (current_state%th%active)
then 454 index_start=index_start+1
456 if (current_state%number_q_fields .gt. 0)
then 457 do n=1, current_state%number_q_fields
471 type(model_state_type),
target,
intent(inout) :: current_state
472 type(prognostic_field_type),
intent(inout) :: zth
473 type(prognostic_field_type),
dimension(:),
intent(inout) :: zq
474 integer,
intent(in) :: first_x_index, second_x_index
476 integer :: index_start, n
479 if (current_state%th%active)
then 482 index_start=index_start+1
484 if (current_state%number_q_fields .gt. 0)
then 485 do n=1, current_state%number_q_fields
492 subroutine handle_convective_fluxes(current_state, current_y_index, current_x_index, horizontal_velocity_at_k2, th, q)
493 type(model_state_type),
target,
intent(inout) :: current_state
494 type(prognostic_field_type),
intent(inout) :: th
495 type(prognostic_field_type),
dimension(:),
intent(inout) :: q
496 integer,
intent(in) :: current_y_index, current_x_index
497 real(kind=DEFAULT_PRECISION),
intent(in) :: horizontal_velocity_at_k2
500 real(kind=DEFAULT_PRECISION) :: ustr
502 ustr=
look(current_state, horizontal_velocity_at_k2)
504 current_state%vis_coefficient%data(1, current_y_index, current_x_index)=&
505 current_state%global_grid%configuration%vertical%czn*ustr**2/ horizontal_velocity_at_k2
506 current_state%diff_coefficient%data(1, current_y_index, current_x_index)=&
507 (von_karman_constant*current_state%global_grid%configuration%vertical%czn*ustr/alphah)/&
508 (current_state%global_grid%configuration%vertical%zlogth- 2.*log(&
509 (1.+sqrt(1.+gammah*von_karman_constant*current_state%fbuoy*(current_state%global_grid%configuration%vertical%zn(2)+z0)&
510 /ustr**3))/ (1.+sqrt(1.+gammah*von_karman_constant*current_state%fbuoy*z0th/ustr**3))))
511 if (current_state%th%active) th%data(1, current_y_index, current_x_index)=th%data(2, current_y_index, current_x_index)+&
512 current_state%surface_temperature_flux*current_state%global_grid%configuration%vertical%dzn(2)/&
513 current_state%diff_coefficient%data(1, current_y_index, current_x_index)
517 if (current_state%number_q_fields .gt. 0)
then 519 q(n)%data(1, current_y_index, current_x_index)=q(n)%data(2, current_y_index, current_x_index)+&
520 current_state%surface_vapour_flux*current_state%global_grid%configuration%vertical%dzn(2)/&
521 current_state%diff_coefficient%data(1, current_y_index, current_x_index)
525 real(kind=DEFAULT_PRECISION) function look(current_state, vel)
526 type(model_state_type),
target,
intent(inout) :: current_state
527 real(kind=DEFAULT_PRECISION),
intent(in) :: vel
529 real(kind=DEFAULT_PRECISION) :: lookup_real_posn
530 integer :: lookup_int_posn
532 lookup_real_posn=1.0_default_precision+
real(current_state%lookup_table_entries-1)*&
533 log(vel/current_state%velmin)*current_state%aloginv
534 lookup_int_posn=int(lookup_real_posn)
536 if (lookup_int_posn .ge. 1)
then 537 if (lookup_int_posn .lt. current_state%lookup_table_entries)
then 538 look=current_state%lookup_table_ustr(lookup_int_posn)+ (lookup_real_posn-
real(lookup_int_posn))*&
539 (current_state%lookup_table_ustr(lookup_int_posn+1)-current_state%lookup_table_ustr(lookup_int_posn))
541 look=vel*current_state%cneut
544 look=vel**(-convective_limit)*current_state%cfc
550 subroutine handle_neutral_fluxes(current_state, current_y_index, current_x_index, horizontal_velocity_at_k2, th, q)
551 type(model_state_type),
target,
intent(inout) :: current_state
552 type(prognostic_field_type),
intent(inout) :: th
553 type(prognostic_field_type),
dimension(:),
intent(inout) :: q
554 integer,
intent(in) :: current_y_index, current_x_index
555 real(kind=DEFAULT_PRECISION) :: horizontal_velocity_at_k2
558 real(kind=DEFAULT_PRECISION) :: ustr
560 ustr=horizontal_velocity_at_k2*current_state%global_grid%configuration%vertical%vk_on_zlogm
561 current_state%vis_coefficient%data(1, current_y_index, current_x_index)=current_state%global_grid%configuration%vertical%czn*&
562 ustr**2/horizontal_velocity_at_k2
563 current_state%diff_coefficient%data(1, current_y_index, current_x_index)=&
564 current_state%vis_coefficient%data(1, current_y_index, current_x_index)*&
565 current_state%global_grid%configuration%vertical%zlogm/(alphah*current_state%global_grid%configuration%vertical%zlogth)
566 if (current_state%th%active) th%data(1, current_y_index, current_x_index)=th%data(2, current_y_index, current_x_index)+&
567 current_state%surface_temperature_flux*current_state%global_grid%configuration%vertical%dzn(2)/&
568 current_state%diff_coefficient%data(1, current_y_index, current_x_index)
571 if (current_state%number_q_fields .gt. 0)
then 573 q(n)%data(1, current_y_index, current_x_index)=q(n)%data(2, current_y_index, current_x_index)+&
574 current_state%surface_vapour_flux*current_state%global_grid%configuration%vertical%dzn(2)/&
575 current_state%diff_coefficient%data(1, current_y_index, current_x_index)
579 subroutine handle_stable_fluxes(current_state, current_y_index, current_x_index, horizontal_velocity_at_k2, th, q)
580 type(model_state_type),
target,
intent(inout) :: current_state
581 type(prognostic_field_type),
intent(inout) :: th
582 type(prognostic_field_type),
dimension(:),
intent(inout) :: q
583 integer,
intent(in) :: current_y_index, current_x_index
584 real(kind=DEFAULT_PRECISION) :: horizontal_velocity_at_k2
586 real(kind=DEFAULT_PRECISION) :: ustr
589 ustr=horizontal_velocity_at_k2*current_state%global_grid%configuration%vertical%vk_on_zlogm
590 if((current_state%fbuoy - 1.e-9_default_precision) .lt. -4.0_default_precision*&
591 von_karman_constant**2*horizontal_velocity_at_k2**3/ (27.0_default_precision*betam*&
592 current_state%global_grid%configuration%vertical%zn(2)*current_state%global_grid%configuration%vertical%zlogm**2))
then 594 current_state%vis_coefficient%data(1, current_y_index, current_x_index)=0.0_default_precision
595 current_state%diff_coefficient%data(1, current_y_index, current_x_index)=0.0_default_precision
597 if (current_state%th%active) th%data(1, current_y_index, current_x_index)=th%data(2, current_y_index, current_x_index)
598 if (current_state%number_q_fields .gt. 0)
then 599 do n=1, current_state%number_q_fields
600 q(n)%data(1, current_y_index, current_x_index)=q(n)%data(2, current_y_index, current_x_index)
604 ustr=ustr/3.0_default_precision*(1.0_default_precision-2.0_default_precision*&
605 cos((acos(-27.0_default_precision*betam*von_karman_constant*current_state%global_grid%configuration%vertical%zn(2)*&
606 current_state%fbuoy/(current_state%global_grid%configuration%vertical%zlogm*&
607 2.0_default_precision*ustr**3)-1.0_default_precision)+ 2.0_default_precision*pi)/3.0_default_precision))
608 current_state%vis_coefficient%data(1, current_y_index, current_x_index)=&
609 current_state%global_grid%configuration%vertical%czn*ustr**2/horizontal_velocity_at_k2
610 current_state%diff_coefficient%data(1, current_y_index, current_x_index)=&
611 current_state%vis_coefficient%data(1, current_y_index, current_x_index)*&
612 (current_state%global_grid%configuration%vertical%zlogm-betam*current_state%global_grid%configuration%vertical%zn(2)*&
613 von_karman_constant*current_state%fbuoy/ustr**3)/(alphah*current_state%global_grid%configuration%vertical%zlogth-betah*&
614 von_karman_constant*current_state%fbuoy* (current_state%global_grid%configuration%vertical%zn(2)+ z0-z0th)/ustr**3)
615 if (current_state%th%active) th%data(1, current_y_index, current_x_index)=th%data(2, current_y_index, current_x_index)+&
616 current_state%surface_temperature_flux*current_state%global_grid%configuration%vertical%dzn(2)/&
617 current_state%diff_coefficient%data(1, current_y_index, current_x_index)
620 if (current_state%number_q_fields .gt. 0)
then 622 q(n)%data(1, current_y_index, current_x_index)=q(n)%data(2, current_y_index, current_x_index)+&
623 current_state%surface_vapour_flux*current_state%global_grid%configuration%vertical%dzn(2)/&
624 current_state%diff_coefficient%data(1, current_y_index, current_x_index)
631 type(model_state_type),
target,
intent(inout) :: current_state
632 type(prognostic_field_type),
intent(inout) :: th
633 type(prognostic_field_type),
dimension(:),
intent(inout) :: q
634 integer,
intent(in) :: current_y_index, current_x_index
635 real(kind=DEFAULT_PRECISION) :: horizontal_velocity_at_k2
637 if (current_state%fbuoy .gt. 0.0_default_precision)
then 639 else if (current_state%fbuoy .eq. 0.0_default_precision)
then 640 call handle_neutral_fluxes(current_state, current_y_index, current_x_index, horizontal_velocity_at_k2, th, q)
642 call handle_stable_fluxes(current_state, current_y_index, current_x_index, horizontal_velocity_at_k2, th, q)
649 type(model_state_type),
target,
intent(inout) :: current_state
650 type(prognostic_field_type),
intent(inout) :: th, zth
651 type(prognostic_field_type),
dimension(:),
intent(inout) :: q, zq
652 real(kind=DEFAULT_PRECISION),
intent(in) :: horizontal_velocity_at_k2
653 integer,
intent(in) :: current_y_index, current_x_index
655 real(kind=DEFAULT_PRECISION) :: dthv_surf, ustr, thvstr
656 integer :: convergence_status, n
658 if (current_state%passive_q)
then 660 dthv_surf = zth%data(2, current_y_index, current_x_index) + &
661 current_state%global_grid%configuration%vertical%thref(2) - current_state%theta_virtual_surf
663 dthv_surf=zth%data(2, current_y_index, current_x_index) + current_state%global_grid%configuration%vertical%thref(2)&
664 *(1.0_default_precision + current_state%cq(current_state%water_vapour_mixing_ratio_index)*&
665 zq(current_state%water_vapour_mixing_ratio_index)%data(2,current_y_index,current_x_index)) - &
666 current_state%theta_virtual_surf
668 convergence_status =
mostbc(current_state, horizontal_velocity_at_k2, dthv_surf,&
669 current_state%global_grid%configuration%vertical%zn(2), ustr, thvstr)
671 current_state%vis_coefficient%data(1, current_y_index, current_x_index)=&
672 current_state%global_grid%configuration%vertical%czn*ustr**2/horizontal_velocity_at_k2
673 current_state%diff_coefficient%data(1, current_y_index, current_x_index)=&
674 current_state%global_grid%configuration%vertical%czn*ustr*thvstr/(dthv_surf+smallp)
675 zth%data(1, current_y_index, current_x_index)=2.0*current_state%theta_surf-zth%data(2, current_y_index, current_x_index)-&
676 (current_state%global_grid%configuration%vertical%thref(2)+current_state%global_grid%configuration%vertical%thref(1))
677 th%data(1, current_y_index, current_x_index)=2.0*current_state%theta_surf-th%data(2, current_y_index, current_x_index)-&
678 (current_state%global_grid%configuration%vertical%thref(2)+current_state%global_grid%configuration%vertical%thref(1))
680 if (current_state%number_q_fields .gt. 0)
then 682 zq(n)%data(1, current_y_index, current_x_index)=zq(n)%data(2, current_y_index, current_x_index)
683 q(n)%data(1, current_y_index, current_x_index)=q(n)%data(2, current_y_index, current_x_index)
684 if (.not. current_state%passive_q)
then 685 zq(current_state%water_vapour_mixing_ratio_index)%data(1,current_y_index,current_x_index)=&
686 2.0_default_precision*current_state%surface_vapour_mixing_ratio-&
687 zq(current_state%water_vapour_mixing_ratio_index)%data(2,current_y_index,current_x_index)
688 q(current_state%water_vapour_mixing_ratio_index)%data(1,current_y_index,current_x_index)=&
689 2.0_default_precision*current_state%surface_vapour_mixing_ratio-&
690 q(current_state%water_vapour_mixing_ratio_index)%data(2,current_y_index,current_x_index)
696 type(model_state_type),
target,
intent(inout) :: current_state
697 type(prognostic_field_type),
intent(inout) :: th
698 type(prognostic_field_type),
dimension(:),
intent(inout) :: q
699 integer,
intent(in) :: current_y_index, current_x_index
703 current_state%vis_coefficient%data(1, current_y_index, current_x_index)=0.0_default_precision
704 current_state%diff_coefficient%data(1, current_y_index, current_x_index)=0.0_default_precision
705 if(current_state%backscatter) current_state%dis%data(1, current_y_index, current_x_index)=0.0_default_precision
706 if(current_state%backscatter .and. current_state%th%active) &
707 current_state%dis_th%data(1, current_y_index, current_x_index)=0.0_default_precision
708 if (current_state%th%active)
then 709 th%data(1, current_y_index, current_x_index) = th%data(2, current_y_index, current_x_index)
711 if (current_state%number_q_fields .gt. 0)
then 712 do n=1, current_state%number_q_fields
713 q(n)%data(1, current_y_index, current_x_index) = q(n)%data(2, current_y_index, current_x_index)
714 if (current_state%backscatter) current_state%disq(n)%data(1, current_y_index, current_x_index) = 0.0_default_precision
734 integer function mostbc(current_state, delu, delt, z1, ustrdg, tstrdg)
735 type(model_state_type),
target,
intent(inout) :: current_state
736 real(kind=DEFAULT_PRECISION),
intent(in) :: delu, delt, z1
737 real(kind=DEFAULT_PRECISION),
intent(out) :: ustrdg, tstrdg
739 if (delt .lt. 0.0_default_precision)
then 740 if (delu .le. smallp)
then 741 ustrdg=0.0_default_precision
746 ustrdg, tstrdg, current_state%global_grid%configuration%vertical)
748 else if (delt .gt. 0.0_default_precision)
then 751 current_state%cmbc, ustrdg, tstrdg)
754 ustrdg=current_state%global_grid%configuration%vertical%vk_on_zlogm*delu
755 tstrdg=0.0_default_precision
761 call log_log(log_warn,
"Richardson number greater than critical value")
763 call log_log(log_error,
"Convergence failure after 200 iterations")
769 real(kind=DEFAULT_PRECISION),
intent(in) :: delu, delt, ellmocon
770 real(kind=DEFAULT_PRECISION),
intent(out) :: ustrdg, tstrdg
771 type(vertical_grid_configuration_type),
intent(inout) :: vertical_grid
774 real(kind=DEFAULT_PRECISION) :: ellmo, psim, psih, x4, xx, xx0, y2, yy, yy0, err_ustr, err_tstr, &
779 ustrl=vertical_grid%vk_on_zlogm*delu
784 ellmo=ustrl*ustrl*ellmocon/tstrl
787 x4=1.0_default_precision-
x4con/ellmo
788 if (x4 .lt. 0.0_default_precision)
call log_log(log_error,
"Negative square root in x4")
791 xx0=sqrt(sqrt(1.0_default_precision-
xx0con / ellmo))
792 psim=2.*( log((xx+1.0_default_precision)/(xx0+1.0_default_precision))-atan(xx)+atan(xx0) )+&
793 log((xx*xx+1.0_default_precision)/(xx0*xx0+1.0_default_precision))
794 ustrpl=von_karman_constant*delu/(vertical_grid%zlogm-psim)
798 if (y2 .lt. 0.0_default_precision)
call log_log(log_error,
"Negative square root in y2")
800 yy0=sqrt(1.0_default_precision-
yy0con/ellmo)
801 psih=2.*log((1.0_default_precision+yy)/(1.0_default_precision+yy0))
802 tstrpl=
tstrconb*delt/(vertical_grid%zlogth-psih)
803 err_ustr=abs((ustrpl-ustrl)/ ustrl)
804 err_tstr=abs((tstrpl-tstrl)/ tstrl)
805 if ((err_tstr .lt.
tolt) .and. (err_ustr .lt.
tolm))
then 811 ustrl=(1.0_default_precision-
smth)*ustrpl+
smth*ustrl
812 tstrl=(1.0_default_precision-
smth)*tstrpl+
smth*tstrl
819 real(kind=DEFAULT_PRECISION),
intent(in) :: delu, delt, zlogm, cmbc
820 real(kind=DEFAULT_PRECISION),
intent(out) :: ustrdg, tstrdg
822 real(kind=DEFAULT_PRECISION) :: am, ah, ee, ff, det
824 am=von_karman_constant*delu
825 ah=von_karman_constant*delt
827 ff=ah*cmbc-
rhmbc*am*am
831 if (ff .gt. 0.0_default_precision)
then 832 if ((ee .lt. 0.0_default_precision).and.(det .gt. 0.0_default_precision))
then 833 ustrdg=(-ee+sqrt(det))*
r2ddbc 834 tstrdg=ustrdg*(am-zlogm*ustrdg)*
rcmbc 837 ustrdg=0.0_default_precision
838 tstrdg=0.0_default_precision
840 else if (
ddbc .eq. 0.0_default_precision)
then 843 tstrdg=delt*ustrdg/delu
846 ustrdg=(-ee+sqrt(det))*
r2ddbc 847 tstrdg=ustrdg*(am-zlogm*ustrdg)*
rcmbc subroutine unpackage_x_wrapping_recv_buffer(current_state, zth, zq, first_x_index, second_x_index)
Unpackages theta and Q fields from the receive buffer into the fields themselves (if enabled) for X...
subroutine compute_lower_boundary_conditions(current_state, current_y_index, current_x_index, zu, zv, zth, th, zq, q)
subroutine package_x_wrapping_send_buffer(current_state, zth, zq, first_x_index, second_x_index)
Packages theta and Q fields (if enabled) into the send buffer for X.
real(kind=default_precision), dimension(:,:,:), allocatable y_wrapping_recv_buffer
real(kind=default_precision) xx0con
real(kind=default_precision), public betah
subroutine compute_using_fixed_surface_fluxes(current_state, current_y_index, current_x_index, horizontal_velocity_at_k2, th, q)
subroutine complete_async_wrapping(current_state, zth, zq)
Completes the asynchronous wrapping if required for periodic boundary conditions. ...
integer, public precision_type
real(kind=default_precision), public z0th
integer, parameter convergence_richardson_too_large
real(kind=default_precision), public gammah
real(kind=default_precision), parameter tolt
real(kind=default_precision), public gammam
integer, parameter, public forward_stepping
type(standard_q_names_type), public standard_q_names
real(kind=default_precision), dimension(:,:,:), allocatable x_wrapping_send_buffer
subroutine compute_using_fixed_surface_temperature(current_state, current_y_index, current_x_index, horizontal_velocity_at_k2, zth, th, zq, q)
real(kind=default_precision) ddbc_x4
integer, parameter, public log_error
Only log ERROR messages.
Contains prognostic field definitions and functions.
A prognostic field which is assumed to be 3D.
subroutine handle_neutral_fluxes(current_state, current_y_index, current_x_index, horizontal_velocity_at_k2, th, q)
real(kind=default_precision) rcmbc
real(kind=default_precision) viscous_courant_coefficient
integer, parameter, public default_precision
MPI communication type which we use for the prognostic and calculation data.
integer, parameter, public z_index
Grid index parameters.
This sets the lower boundary conditions for theta and the q variables.
real(kind=default_precision), public smallp
subroutine timestep_callback(current_state)
real(kind=default_precision), parameter tolm
integer, dimension(4) wrapping_comm_requests
Contains common definitions for the data and datatypes used by MONC.
real(kind=default_precision) tstrcona
The ModelState which represents the current state of a run.
real(kind=default_precision) function look(current_state, vel)
logical function, public is_component_enabled(options_database, component_name)
Determines whether or not a specific component is registered and enabled.
subroutine, public log_master_log(level, message)
Will log just from the master process.
integer y_wrapping_target_id
real(kind=default_precision), public z0
Description of a component.
integer, parameter, public prescribed_surface_fluxes
real(kind=default_precision) y2con
integer, parameter convergence_failure
real(kind=default_precision), public von_karman_constant
The configuration of the grid vertically.
type(component_descriptor_type) function, public lowerbc_get_descriptor()
Descriptor of this component for registration.
real(kind=default_precision) r2ddbc
subroutine, public log_log(level, message, str)
Logs a message at the specified level. If the level is above the current level then the message is ig...
real(kind=default_precision), public pi
subroutine register_async_wrapping_recv_requests(current_state)
Registers asynchronous wrapping recv requests as needed.
Scientific constant values used throughout simulations. Each has a default value and this can be over...
This manages the Q variables and specifically the mapping between names and the index that they are s...
subroutine handle_convective_fluxes(current_state, current_y_index, current_x_index, horizontal_velocity_at_k2, th, q)
integer, parameter convergence_success
Interfaces and types that MONC components must specify.
real(kind=default_precision) ddbc
integer function solve_monin_obukhov_stable_case(delu, delt, zlogm, cmbc, ustrdg, tstrdg)
integer, parameter, public log_warn
Log WARNING and ERROR messages.
real(kind=default_precision) eecon
subroutine unpackage_y_wrapping_recv_buffer(current_state, zth, zq, first_y_index, second_y_index)
Unpackages theta and Q fields from the receive buffer into the fields themselves (if enabled) for Y...
real(kind=default_precision) yy0con
integer function solve_monin_obukhov_unstable_case(delu, delt, ellmocon, ustrdg, tstrdg, vertical_grid)
subroutine initialisation_callback(current_state)
real(kind=default_precision), public convective_limit
subroutine package_y_wrapping_send_buffer(current_state, zth, zq, first_y_index, second_y_index)
Packages theta and Q fields (if enabled) into the send buffer for Y.
integer, parameter, public prescribed_surface_values
Functionality to support the different types of grid and abstraction between global grids and local o...
real(kind=default_precision) rhmbc
real(kind=default_precision), public alphah
subroutine handle_stable_fluxes(current_state, current_y_index, current_x_index, horizontal_velocity_at_k2, th, q)
subroutine simple_boundary_values(current_state, current_y_index, current_x_index, th, q)
subroutine allocate_applicable_fields(current_state)
real(kind=default_precision), public betam
real(kind=default_precision), dimension(:,:,:), allocatable y_wrapping_send_buffer
integer function mostbc(current_state, delu, delt, z1, ustrdg, tstrdg)
Solves the Monin-Obukhov equations in the case of specified surface values of temperature and mixing ...
subroutine finalisation_callback(current_state)
real(kind=default_precision) tstrconb
real(kind=default_precision) x4con
real(kind=default_precision), dimension(:,:,:), allocatable x_wrapping_recv_buffer
The model state which represents the current state of a run.
integer, parameter, public y_index
real(kind=default_precision), parameter smth
integer x_wrapping_target_id
integer, parameter, public x_index
integer function, public get_q_index(name, assigning_component)
Add in a new entry into the register if the name does not already exist or return the index of the pr...