17 use mpi
, only : mpi_max, mpi_sum, mpi_comm_world, mpi_request_null, mpi_statuses_ignore
26 real(kind=DEFAULT_PRECISION) :: n, s, e, w
27 real(kind=DEFAULT_PRECISION),
dimension(:),
allocatable :: u, d, p, lu_d, lu_u, vol
35 real(kind=DEFAULT_PRECISION),
parameter ::
tiny = 1.0e-16
38 real(kind=DEFAULT_PRECISION),
dimension(:,:,:),
allocatable ::
psource,
prev_p 58 type(model_state_type),
target,
intent(inout) :: current_state
60 if (.not. is_component_enabled(current_state%options_database,
"diverr"))
then 61 call log_master_log(log_error,
"The iterative solver component requires the diverr component to be enabled")
64 tolerance=options_get_real(current_state%options_database,
"tolerance")
65 max_iterations=options_get_integer(current_state%options_database,
"max_iterations")
67 symm_prob=options_get_logical(current_state%options_database,
"symm_prob")
69 call init_halo_communication(current_state, get_single_field_per_halo_cell,
halo_swap_state, 1, .false.)
71 allocate(
psource(current_state%local_grid%size(z_index) + current_state%local_grid%halo_size(z_index) * 2, &
72 current_state%local_grid%size(y_index) + current_state%local_grid%halo_size(y_index) * 2, &
73 current_state%local_grid%size(x_index) + current_state%local_grid%halo_size(x_index) * 2),&
74 prev_p(current_state%local_grid%size(z_index) + current_state%local_grid%halo_size(z_index) * 2, &
75 current_state%local_grid%size(y_index) + current_state%local_grid%halo_size(y_index) * 2, &
76 current_state%local_grid%size(x_index) + current_state%local_grid%halo_size(x_index) * 2))
85 type(model_state_type),
target,
intent(inout) :: current_state
87 integer :: i_strt, i_end, j_strt, j_end, k_end
89 i_strt = current_state%local_grid%local_domain_start_index(x_index)
90 i_end = current_state%local_grid%local_domain_end_index(x_index)
91 j_strt = current_state%local_grid%local_domain_start_index(y_index)
92 j_end = current_state%local_grid%local_domain_end_index(y_index)
93 k_end = current_state%local_grid%size(z_index)
96 current_state%local_grid%halo_size(x_index))
105 current_state%p%data=0.0_default_precision
109 current_state%p%data=
prev_p 113 call cg_solver(current_state,
a, current_state%p%data,
psource, i_strt, i_end, j_strt, j_end, k_end)
115 call bicgstab(current_state,
a, current_state%p%data,
psource, i_strt, i_end, j_strt, j_end, k_end)
118 prev_p=current_state%p%data
124 type(model_state_type),
target,
intent(inout) :: current_state
135 subroutine bicgstab(current_state, A, x, b, i_strt, i_end, j_strt, j_end, k_end)
136 type(model_state_type),
target,
intent(inout) :: current_state
138 real(kind=DEFAULT_PRECISION),
dimension(:,:,:),
intent(inout) :: x
139 real(kind=DEFAULT_PRECISION),
dimension(:,:,:),
intent(in) :: b
140 integer,
intent(in) :: i_strt, i_end, j_strt, j_end, k_end
142 integer :: it, i, j, k
143 real(kind=DEFAULT_PRECISION) :: sc_err, alf, omg, nrm, my_rho, bet, tt, ts, ss, err, init_err, inner_prod_results(3)
144 real(kind=DEFAULT_PRECISION),
dimension(current_state%local_grid%size(Z_INDEX) + &
current_state%local_grid%halo_size(Z_INDEX) * 2, &
current_state%local_grid%size(Y_INDEX) + current_state%local_grid%halo_size(Y_INDEX) * 2, &
current_state%local_grid%size(X_INDEX) + current_state%local_grid%halo_size(X_INDEX) * 2) :: Ax, r, cr, pp, v, t, s, cs
147 sc_err = sqrt(
inner_prod(current_state, b, b, i_strt, i_end, j_strt, j_end, k_end))
148 sc_err = max(sc_err, 0.0001_default_precision)
151 call calc_ax(current_state, a, x, ax)
156 r(k,j,i) = b(k,j,i) - ax(k,j,i)
162 my_rho =
inner_prod(current_state, r, r, i_strt, i_end, j_strt, j_end, k_end)
163 err = sqrt(my_rho)/sc_err
166 alf = 1.0_default_precision
167 omg = 1.0_default_precision
168 nrm = 1.0_default_precision
172 if (it > 1) my_rho =
inner_prod(current_state, r, cr, i_strt, i_end, j_strt, j_end, k_end)
173 bet = (my_rho/nrm) * (alf/omg)
180 t(k,j,i) = r(k,j,i) - bet*omg*v(k,j,i)
188 pp(k,j,i) = s(k,j,i) + bet*pp(k,j,i)
193 call calc_ax(current_state, a, pp, v)
194 nrm =
inner_prod(current_state, cr, v, i_strt, i_end, j_strt, j_end, k_end)
200 s(k,j,i) = r(k,j,i) - alf*v(k,j,i)
206 call calc_ax(current_state, a, cs, t)
208 inner_prod_results=
inner_prod_three_way(current_state, t, s, i_strt, i_end, j_strt, j_end, k_end)
209 tt = inner_prod_results(1)
210 ts = inner_prod_results(2)
211 ss = inner_prod_results(3)
213 x = x + alf*pp + omg*cs
217 r(k,j,i) = s(k,j,i) - omg*t(k,j,i)
223 if (abs(omg) <
tiny)
then 224 call log_log(log_warn,
"Convergence problem, omega="//conv_to_string(omg))
227 err = sqrt(ss - 2*omg*ts + omg**2 *tt)/sc_err
233 call log_log(log_warn,
"Convergence failed, RNorm="//conv_to_string(err, exponent=.true.))
234 else if (current_state%parallel%my_rank==0 .and. log_get_logging_level() .eq. log_debug)
then 235 call log_log(log_debug,
"Converged in "//trim(conv_to_string(it))//
" iterations with RNorm="//&
236 trim(conv_to_string(err, 5, .true.))//
" initial norm="//trim(conv_to_string(init_err, 5, .true.)))
245 subroutine cg_solver(current_state, A, x, b, i_strt, i_end, j_strt, j_end, k_end)
246 type(model_state_type),
target,
intent(inout) :: current_state
248 real(kind=DEFAULT_PRECISION),
dimension(:,:,:),
intent(inout) :: x
249 real(kind=DEFAULT_PRECISION),
dimension(:,:,:),
intent(in) :: b
250 integer,
intent(in) :: i_strt, i_end, j_strt, j_end, k_end
252 integer :: it, k, i, j
253 real(kind=DEFAULT_PRECISION) :: sc_err, alf, bet, err, init_err, rho
254 real(kind=DEFAULT_PRECISION),
dimension(current_state%local_grid%size(Z_INDEX) + &
current_state%local_grid%halo_size(Z_INDEX) * 2, &
current_state%local_grid%size(Y_INDEX) + current_state%local_grid%halo_size(Y_INDEX) * 2, &
current_state%local_grid%size(X_INDEX) + current_state%local_grid%halo_size(X_INDEX) * 2) :: Ax, r, z, p
257 do i=current_state%local_grid%local_domain_start_index(x_index), current_state%local_grid%local_domain_end_index(x_index)
258 do j=current_state%local_grid%local_domain_start_index(y_index), current_state%local_grid%local_domain_end_index(y_index)
260 r(1,j,i) = 0.0_default_precision
261 do k=2,current_state%local_grid%size(z_index)
262 r(k,j,i) = b(k,j,i) * a%vol(k)
269 call calc_ax(current_state, a, x, ax)
271 sc_err = sqrt(
inner_prod(current_state, r, r, i_strt, i_end, j_strt, j_end, k_end))
272 sc_err = max(sc_err, 0.0001_default_precision)
274 init_err = sqrt(
inner_prod(current_state, r, r, i_strt, i_end, j_strt, j_end, k_end))/sc_err
279 rho =
inner_prod(current_state, p, r, i_strt, i_end, j_strt, j_end, k_end)
283 alf =
inner_prod(current_state, z, r, i_strt, i_end, j_strt, j_end, k_end)
289 call calc_ax(current_state, a, p, ax)
290 alf = alf/
inner_prod(current_state, p, ax, i_strt, i_end, j_strt, j_end, k_end)
294 err = sqrt(
inner_prod(current_state, r, r, i_strt, i_end, j_strt, j_end, k_end))/sc_err
298 if( current_state%parallel%my_rank == 0 ) print*,it, err, init_err
301 call log_log(log_warn,
"Convergence failed, RNorm="//conv_to_string(err, exponent=.true.))
302 else if (current_state%parallel%my_rank==0 .and. log_get_logging_level() .eq. log_debug)
then 303 call log_log(log_debug,
"Converged in "//trim(conv_to_string(it))//
" iterations with RNorm="//&
304 trim(conv_to_string(err, 5, .true.))//
" initial norm="//trim(conv_to_string(init_err, 5, .true.)))
314 subroutine precond(current_state, A, s, r, preits)
315 type(model_state_type),
target,
intent(inout) :: current_state
316 real(kind=DEFAULT_PRECISION),
dimension(:,:,:),
intent(in) :: r
317 real(kind=DEFAULT_PRECISION),
dimension(:,:,:),
intent(inout) :: s
318 integer,
intent(in) :: preits
321 real(kind=DEFAULT_PRECISION),
dimension(current_state%local_grid%size(Z_INDEX) + &
current_state%local_grid%halo_size(Z_INDEX) * 2, current_state%local_grid%size(Y_INDEX) + &
current_state%local_grid%halo_size(Y_INDEX) * 2, current_state%local_grid%size(X_INDEX) + &
current_state%local_grid%halo_size(X_INDEX) * 2) :: t
322 real(kind=DEFAULT_PRECISION),
dimension(current_state%local_grid%size(Z_INDEX)) :: s_k
323 integer :: it, i, j, k
325 if (preits .lt. 0)
then 330 do i=current_state%local_grid%local_domain_start_index(x_index), current_state%local_grid%local_domain_end_index(x_index)
331 do j=current_state%local_grid%local_domain_start_index(y_index), current_state%local_grid%local_domain_end_index(y_index)
332 s(1,j,i) = 0.0_default_precision
334 s(k,j,i)=r(k,j,i)*a%LU_d(k)
335 do k=3,current_state%local_grid%size(z_index)
336 s(k,j,i)=(r(k,j,i) - a%d(k)*s(k-1,j,i))*a%lu_d(k)
338 do k=current_state%local_grid%size(z_index)-1, 2, -1
339 s(k,j,i)=s(k,j,i) - a%lu_u(k)*s(k+1,j,i)
345 call calc_ax(current_state, a, s, t)
346 do i=current_state%local_grid%local_domain_start_index(x_index), current_state%local_grid%local_domain_end_index(x_index)
347 do j=current_state%local_grid%local_domain_start_index(y_index), current_state%local_grid%local_domain_end_index(y_index)
349 s_k(k)=(r(k,j,i) - t(k,j,i))*a%lu_d(k)
350 do k=3,current_state%local_grid%size(z_index)
351 s_k(k)=(r(k,j,i) - t(k,j,i) - a%d(k)*s_k(k-1))*a%lu_d(k)
353 k=current_state%local_grid%size(z_index)
354 s(k,j,i)=s(k,j,i)+s_k(k)
355 do k=current_state%local_grid%size(z_index)-1, 2, -1
356 s_k(k)=s_k(k) - a%lu_u(k)*s_k(k+1)
369 subroutine calc_ax(current_state, A, x, Ax)
370 type(model_state_type),
target,
intent(inout) :: current_state
372 real(kind=DEFAULT_PRECISION),
dimension(:,:,:),
target,
intent(inout) :: x, Ax
374 integer :: i, k, j, n, istart, iend, jstart, jend
375 type(field_data_wrapper_type) :: source_data
382 ax(1,:,:) = 0.0_default_precision
386 istart=current_state%local_grid%local_domain_start_index(x_index)+1
387 iend=current_state%local_grid%local_domain_end_index(x_index)-1
388 jstart=current_state%local_grid%local_domain_start_index(y_index)+1
389 jend=current_state%local_grid%local_domain_end_index(y_index)-1
391 istart=current_state%local_grid%local_domain_start_index(x_index)
392 iend=current_state%local_grid%local_domain_start_index(x_index)
394 istart=current_state%local_grid%local_domain_end_index(x_index)
395 iend=current_state%local_grid%local_domain_end_index(x_index)
397 jstart=current_state%local_grid%local_domain_start_index(y_index)
398 jend=current_state%local_grid%local_domain_start_index(y_index)
399 istart=current_state%local_grid%local_domain_start_index(x_index)
400 iend=current_state%local_grid%local_domain_end_index(x_index)
402 jstart=current_state%local_grid%local_domain_end_index(y_index)
403 jend=current_state%local_grid%local_domain_end_index(y_index)
408 ax(k,j,i)=a%vol(k)*(a%n*(x(k,j,i+1)+x(k,j,i-1))+a%e*(x(k,j+1,i)+x(k,j-1,i)))+ a%u(k)*x(k+1,j,i)+a%p(k)*x(k,j,i)
409 do k=3,current_state%local_grid%size(z_index)-1
410 ax(k,j,i)=a%vol(k)*(a%n*(x(k,j,i+1)+x(k,j,i-1))+a%e*(x(k,j+1,i)+x(k,j-1,i)))+&
411 a%u(k)*x(k+1,j,i)+a%d(k)*x(k-1,j,i)+a%p(k)*x(k,j,i)
413 k=current_state%local_grid%size(z_index)
414 ax(k,j,i) = a%vol(k)*(a%n*(x(k,j,i+1)+x(k,j,i-1))+a%e*(x(k,j+1,i)+x(k,j-1,i)))+ a%d(k)*x(k-1,j,i)+a%p(k)*x(k,j,i)
425 istart=current_state%local_grid%local_domain_start_index(x_index)+1
426 iend=current_state%local_grid%local_domain_end_index(x_index)-1
427 jstart=current_state%local_grid%local_domain_start_index(y_index)+1
428 jend=current_state%local_grid%local_domain_end_index(y_index)-1
430 istart=current_state%local_grid%local_domain_start_index(x_index)
431 iend=current_state%local_grid%local_domain_start_index(x_index)
433 istart=current_state%local_grid%local_domain_end_index(x_index)
434 iend=current_state%local_grid%local_domain_end_index(x_index)
436 jstart=current_state%local_grid%local_domain_start_index(y_index)
437 jend=current_state%local_grid%local_domain_start_index(y_index)
438 istart=current_state%local_grid%local_domain_start_index(x_index)
439 iend=current_state%local_grid%local_domain_end_index(x_index)
441 jstart=current_state%local_grid%local_domain_end_index(y_index)
442 jend=current_state%local_grid%local_domain_end_index(y_index)
447 ax(k,j,i)=a%n*(x(k,j,i+1)+x(k,j,i-1))+a%e*(x(k,j+1,i)+x(k,j-1,i))+ a%u(k)*x(k+1,j,i)+a%p(k)*x(k,j,i)
448 do k=3,current_state%local_grid%size(z_index)-1
449 ax(k,j,i)=a%n*(x(k,j,i+1)+x(k,j,i-1))+a%e*(x(k,j+1,i)+x(k,j-1,i))+&
450 a%u(k)*x(k+1,j,i)+a%d(k)*x(k-1,j,i)+a%p(k)*x(k,j,i)
452 k=current_state%local_grid%size(z_index)
453 ax(k,j,i) = a%n*(x(k,j,i+1)+x(k,j,i-1))+a%e*(x(k,j+1,i)+x(k,j-1,i))+ a%d(k)*x(k-1,j,i)+a%p(k)*x(k,j,i)
469 real(kind=DEFAULT_PRECISION) function inner_prod(current_state, x, y, i_strt, i_end, j_strt, j_end, k_end)
470 type(model_state_type),
target,
intent(inout) :: current_state
471 real(kind=DEFAULT_PRECISION),
dimension(:,:,:),
intent(in) :: x, y
472 integer,
intent(in) :: i_strt, i_end, j_strt, j_end, k_end
474 real(kind=DEFAULT_PRECISION) :: local_sum, global_sum
475 integer :: ierr, i, j, k
477 local_sum=0.0_default_precision
482 local_sum=local_sum+x(k,j,i)*y(k,j,i)
487 call mpi_allreduce(local_sum, global_sum, 1, precision_type, mpi_sum, current_state%parallel%monc_communicator, ierr)
498 type(model_state_type),
target,
intent(inout) :: current_state
499 integer,
intent(in) :: i_strt, i_end, j_strt, j_end, k_end
500 real(kind=DEFAULT_PRECISION),
dimension(:,:,:),
intent(in) :: t, s
501 real(kind=DEFAULT_PRECISION),
dimension(3) :: inner_prod_three_way
503 real(kind=DEFAULT_PRECISION),
dimension(3) :: local_sum, global_sum
504 integer :: ierr, i, j, k
506 local_sum(1)=0.0_default_precision
507 local_sum(2)=0.0_default_precision
508 local_sum(3)=0.0_default_precision
513 local_sum(1)=local_sum(1)+t(k,j,i)*t(k,j,i)
514 local_sum(2)=local_sum(2)+t(k,j,i)*s(k,j,i)
515 local_sum(3)=local_sum(3)+s(k,j,i)*s(k,j,i)
520 call mpi_allreduce(local_sum, global_sum, 3, precision_type, mpi_sum, current_state%parallel%monc_communicator, ierr)
521 inner_prod_three_way=global_sum
529 type(grid_configuration_type),
intent(inout) :: grid_configuration
531 integer,
intent(in) :: z_size
534 real(kind=DEFAULT_PRECISION) :: d_sc, concat_scalars
536 a%n=grid_configuration%horizontal%cx*grid_configuration%horizontal%cx
538 a%e=grid_configuration%horizontal%cy*grid_configuration%horizontal%cy
540 concat_scalars=a%n+a%s+a%e+a%w
543 a%vol(k)=grid_configuration%vertical%dz(k)
544 d_sc=1.0/grid_configuration%vertical%rhon(k)
546 d_sc=grid_configuration%vertical%rdz(k) / grid_configuration%vertical%rhon(k)
551 a%u(k)=0.0_default_precision
553 a%u(k)=grid_configuration%vertical%rho(k)*grid_configuration%vertical%rdzn(k+1)
556 a%d(k)=0.0_default_precision
558 a%d(k)=grid_configuration%vertical%rho(k-1)*grid_configuration%vertical%rdzn(k)
560 a%p(k) = d_sc * (-(a%u(k) + a%d(k))) - concat_scalars * a%vol(k)
565 a%lu_d(k)=1.0_default_precision/a%p(k)
566 a%lu_u(k)=a%lu_d(k)*a%u(k)
568 a%lu_d(k)=1.0_default_precision/(a%p(k) - a%d(k)*a%lu_u(k-1))
569 a%lu_u(k)=a%u(k)*a%lu_d(k)
576 type(model_state_type),
target,
intent(inout) :: current_state
580 call mpi_allreduce(current_state%local_divmax, current_state%global_divmax, 1, precision_type, mpi_max, &
581 current_state%parallel%monc_communicator, ierr)
593 pid_location, current_page, source_data)
594 type(model_state_type),
intent(inout) :: current_state
595 integer,
intent(in) :: dim, pid_location, source_index
596 integer,
intent(inout) :: current_page(:)
597 type(neighbour_description_type),
intent(inout) :: neighbour_description
598 type(field_data_wrapper_type),
dimension(:),
intent(in),
optional :: source_data
600 call copy_field_to_buffer(current_state%local_grid, neighbour_description%send_halo_buffer, current_state%p%data, &
601 dim, source_index, current_page(pid_location))
603 current_page(pid_location)=current_page(pid_location)+1
615 pid_location, current_page, source_data)
616 type(model_state_type),
intent(inout) :: current_state
617 integer,
intent(in) :: dim, pid_location, source_index
618 integer,
intent(inout) :: current_page(:)
619 type(neighbour_description_type),
intent(inout) :: neighbour_description
620 type(field_data_wrapper_type),
dimension(:),
intent(in),
optional :: source_data
622 type(field_data_wrapper_type) :: selected_source
624 selected_source=source_data(1)
626 call copy_field_to_buffer(current_state%local_grid, neighbour_description%send_halo_buffer, selected_source%data, &
627 dim, source_index, current_page(pid_location))
629 current_page(pid_location)=current_page(pid_location)+1
641 neighbour_location, current_page, source_data)
642 type(model_state_type),
intent(inout) :: current_state
643 integer,
intent(in) :: dim, target_index, neighbour_location
644 integer,
intent(inout) :: current_page(:)
645 type(neighbour_description_type),
intent(inout) :: neighbour_description
646 type(field_data_wrapper_type),
dimension(:),
intent(in),
optional :: source_data
648 call copy_buffer_to_field(current_state%local_grid, neighbour_description%recv_halo_buffer, current_state%p%data, &
649 dim, target_index, current_page(neighbour_location))
651 current_page(neighbour_location)=current_page(neighbour_location)+1
663 neighbour_location, current_page, source_data)
664 type(model_state_type),
intent(inout) :: current_state
665 integer,
intent(in) :: dim, target_index, neighbour_location
666 integer,
intent(inout) :: current_page(:)
667 type(neighbour_description_type),
intent(inout) :: neighbour_description
668 type(field_data_wrapper_type),
dimension(:),
intent(in),
optional :: source_data
670 type(field_data_wrapper_type) :: selected_source
672 selected_source=source_data(1)
674 call copy_buffer_to_field(current_state%local_grid, neighbour_description%recv_halo_buffer, selected_source%data, &
675 dim, target_index, current_page(neighbour_location))
677 current_page(neighbour_location)=current_page(neighbour_location)+1
684 type(model_state_type),
intent(inout) :: current_state
685 integer,
intent(in) :: halo_depth
686 logical,
intent(in) :: involve_corners
687 type(field_data_wrapper_type),
dimension(:),
intent(in),
optional :: source_data
689 call perform_local_data_copy_for_field(current_state%p%data, current_state%local_grid, &
690 current_state%parallel%my_rank, halo_depth, involve_corners)
697 type(model_state_type),
intent(inout) :: current_state
698 integer,
intent(in) :: halo_depth
699 logical,
intent(in) :: involve_corners
700 type(field_data_wrapper_type),
dimension(:),
intent(in),
optional :: source_data
702 type(field_data_wrapper_type) :: selected_source
704 selected_source=source_data(1)
706 call perform_local_data_copy_for_field(selected_source%data, current_state%local_grid, &
707 current_state%parallel%my_rank, halo_depth, involve_corners)
714 integer,
intent(in) :: z_size
717 allocate(create_problem_matrix%u(z_size), create_problem_matrix%d(z_size), create_problem_matrix%p(z_size), &
718 create_problem_matrix%lu_u(z_size), create_problem_matrix%lu_d(z_size), create_problem_matrix%vol(z_size))
727 type(model_state_type),
target,
intent(inout) :: current_state
728 integer,
intent(in) :: y_halo_size, x_halo_size
730 integer :: ierr, combined_handles(2), i, j, k
732 combined_handles(1)=current_state%psrce_x_hs_recv_request
733 combined_handles(2)=current_state%psrce_y_hs_recv_request
734 call mpi_waitall(2, combined_handles, mpi_statuses_ignore, ierr)
736 do j=current_state%local_grid%local_domain_start_index(y_index), current_state%local_grid%local_domain_end_index(y_index)
737 do k=2,current_state%local_grid%size(z_index)
739 current_state%p%data(k,j,x_halo_size+1)=current_state%p%data(k,j,x_halo_size+1)-&
740 current_state%psrce_recv_buffer_x(k-1,j-x_halo_size)
743 if (j .gt. y_halo_size+1) current_state%p%data(k, j, x_halo_size+1)=current_state%p%data(k, j, x_halo_size+1)-&
744 current_state%global_grid%configuration%horizontal%cy * current_state%sv%data(k, j-1, x_halo_size+1)
750 do i=current_state%local_grid%local_domain_start_index(x_index), current_state%local_grid%local_domain_end_index(x_index)
751 do k=2,current_state%local_grid%size(z_index)
752 current_state%p%data(k,y_halo_size+1,i)=current_state%p%data(k,y_halo_size+1,i)-&
753 current_state%psrce_recv_buffer_y(k-1,i-y_halo_size)
758 combined_handles(1)=current_state%psrce_x_hs_send_request
759 combined_handles(2)=current_state%psrce_y_hs_send_request
760 call mpi_waitall(2, combined_handles, mpi_statuses_ignore, ierr)
763 integer, public precision_type
subroutine, public init_halo_communication(current_state, get_fields_per_halo_cell, halo_state, halo_depth, involve_corners)
Initialises a halo swapping state, by determining the neighbours, size of data in each swap and alloc...
type(halo_communication_type), save halo_swap_state
The halo swap state as initialised by that module.
real(kind=default_precision) tolerance
subroutine, public blocking_halo_swap(current_state, halo_swap_state, copy_to_halo_buffer, perform_local_data_copy, copy_from_halo_buffer, copy_corners_to_halo_buffer, copy_from_halo_buffer_to_corner, source_data)
Performs the entire halo swap operation, this is simply a wrapper around the nonblocking initiate and...
subroutine finalisation_callback(current_state)
Called as MONC is shutting down and frees the halo swap state and deallocates local data...
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.
subroutine perform_local_data_copy_for_calc_ax(current_state, halo_depth, involve_corners, source_data)
Does a local data copy for halo swapping cells with wrap around (to maintain periodic boundary condit...
integer, parameter, public log_error
Only log ERROR messages.
Contains the types used for communication, holding the state of communications and supporting activit...
subroutine set_matrix_for_poisson(grid_configuration, A, z_size)
Sets the values of the provided matrix to solve the poisson equation.
A helper type to abstract the concrete details of the matrix.
subroutine deduce_global_divmax(current_state)
Determines the global divmax which is written into the current state.
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.
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...
subroutine initialisation_callback(current_state)
Initialisation callback hook which will set up the halo swapping state and allocate some data...
Contains common definitions for the data and datatypes used by MONC.
The ModelState which represents the current state of a run.
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, parameter, public log_debug
Log DEBUG, INFO, WARNING and ERROR messages.
Conversion between common inbuilt FORTRAN data types.
Converts data types to strings.
Description of a component.
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...
Wraps the dimensional configuration types.
subroutine, public initiate_nonblocking_halo_swap(current_state, halo_swap_state, copy_to_halo_buffer, copy_corners_to_halo_buffer, source_data)
Initiates a non blocking halo swap, this registers the receive requests, copies data into the send bu...
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), parameter tiny
Minimum residual - if we go below this then something has gone wrong.
type(component_descriptor_type) function, public iterativesolver_get_descriptor()
Descriptor of the iterative solver component used by the registry.
real(kind=default_precision) function inner_prod(current_state, x, y, i_strt, i_end, j_strt, j_end, k_end)
Returns the global inner product of two vectors, ignoring the halo cells.
subroutine copy_halo_buffer_to_calc_ax(current_state, neighbour_description, dim, target_index, neighbour_location, current_page, source_data)
Copies the halo buffer to halo location for the source field as required in the calc_Ax procedure...
Maintains the state of a halo swap and contains buffers, neighbours etc.
Map data structure that holds string (length 20 maximum) key value pairs.
subroutine copy_halo_buffer_to_p(current_state, neighbour_description, dim, target_index, neighbour_location, current_page, source_data)
Copies the halo buffer to halo location for the p field.
real(kind=default_precision), dimension(:,:,:), allocatable psource
integer function, public get_single_field_per_halo_cell(current_state)
A very common function, which returns a single field per halo cell which is used to halo swap just on...
Interfaces and types that MONC components must specify.
real(kind=default_precision), dimension(:,:,:), allocatable prev_p
Passed to BiCGStab as the RHS.
Defined the local grid, i.e. the grid held on this process after decomposition.
Collection data structures.
subroutine cg_solver(current_state, A, x, b, i_strt, i_end, j_strt, j_end, k_end)
Performs the preconditioned conjugate gradient method.
subroutine perform_local_data_copy_for_p(current_state, halo_depth, involve_corners, source_data)
Does local data copying for P variable halo swap.
Provides the mechanism for halo swapping. This module contains the functionality required to determin...
real(kind=default_precision) relaxation
Solving tollerance.
integer, parameter, public log_warn
Log WARNING and ERROR messages.
Describes the neighbours of a process in a specific dimension and contains the communication buffers ...
subroutine complete_psrce_calculation(current_state, y_halo_size, x_halo_size)
Completes the psrce calculation by waiting on all outstanding psrce communications to complete and th...
This is the iterative pressure solver and uses a Jacobi preconditioned BiCGStab which we implement he...
subroutine precond(current_state, A, s, r, preits)
Jacobi preconditioner.
subroutine, public copy_field_to_buffer(local_grid, halo_buffer, field_data, dim, source_index, halo_page)
Copies prognostic field data to send buffer for specific field, dimension, halo cell.
subroutine bicgstab(current_state, A, x, b, i_strt, i_end, j_strt, j_end, k_end)
Performs the BiCGStab KS method.
subroutine calc_ax(current_state, A, x, Ax)
Calculates A * x.
real(kind=default_precision) function, public options_get_real(options_database, key, index)
Retrieves a real value from the database that matches the provided key.
subroutine copy_p_to_halo_buffer(current_state, neighbour_description, dim, source_index, pid_location, current_page, source_data)
Copies the p field data to halo buffers for a specific process in a dimension and halo cell...
type(matrix_type) function create_problem_matrix(z_size)
Creates a problem matrix, allocating the required data based upon the column size.
Functionality to support the different types of grid and abstraction between global grids and local o...
integer function, public options_get_integer(options_database, key, index)
Retrieves an integer value from the database that matches the provided key.
subroutine, public finalise_halo_communication(halo_swap_state)
Finalises the halo swap represented by the state by freeing up all the allocated memory.
Manages the options database. Contains administration functions and deduce runtime options from the c...
logical function, public options_get_logical(options_database, key, index)
Retrieves a logical value from the database that matches the provided key.
integer preconditioner_iterations
Number of preconditioner iterations to perform per call.
real(kind=default_precision) function, dimension(3) inner_prod_three_way(current_state, t, s, i_strt, i_end, j_strt, j_end, k_end)
Returns the global inner product of a pair of vectors, ignoring the halo cells for three separate pai...
integer max_iterations
Maximum number of BiCGStab iterations.
The model state which represents the current state of a run.
integer function, public log_get_logging_level()
Retrieves the current logging level.
integer, parameter, public y_index
integer, parameter, public x_index
subroutine copy_calc_ax_to_halo_buffer(current_state, neighbour_description, dim, source_index, pid_location, current_page, source_data)
Copies the source field data to halo buffers for a specific process in a dimension and halo cell - fo...
subroutine timestep_callback(current_state)
Timestep callback, this ignores all but the last column where it calls the solver.