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...