MONC
petsc_solver.F90
Go to the documentation of this file.
1 
2 #include "petsc/finclude/petscvecdef.h"
3 #include "petsc/finclude/petscmatdef.h"
4 #include "petsc/finclude/petsckspdef.h"
5 #include "petsc/finclude/petscdmdadef.h"
8  use state_mod, only : model_state_type
17  use petscvec
18  use petscmat
19  use petscksp
20  use petscsys
21  use petscdmda
22  implicit none
23 
24 #ifndef TEST_MODE
25  private
26 #endif
27 
28  ksp :: ksp
29  dm :: da
32 
33  real(kind=DEFAULT_PRECISION), dimension(:,:,:), allocatable :: p_source, prev_p
34  real(kind=DEFAULT_PRECISION) :: cx, cy
35  real(kind=DEFAULT_PRECISION), dimension(:), allocatable :: rdzn, rdz, rho, rhon, dz, dzn
36 
38 
39  contains
40 
44  petsc_solver_get_descriptor%name="petsc_solver"
45  petsc_solver_get_descriptor%version=0.1
49  end function petsc_solver_get_descriptor
50 
51  subroutine finalisation_callback(current_state)
52  type(model_state_type), target, intent(inout) :: current_state
53 
54  petscerrorcode :: ierr
55 
56  call petscfinalize(ierr)
57  end subroutine finalisation_callback
58 
62  subroutine init_callback(current_state)
63  type(model_state_type), target, intent(inout) :: current_state
64 
65  petscerrorcode :: ierr
66  ksptype :: ksp_type
67  pc :: pc_instance
68  pctype :: pc_type
69  integer :: y_lengths(current_state%parallel%dim_sizes(y_index)), x_lengths(current_state%parallel%dim_sizes(x_index))
70  integer new_communicator, my_transposed_rank, x_rank_val, y_rank_val
71 
72  call apply_dimension_bounds(current_state%global_grid%size(y_index), current_state%parallel%dim_sizes(y_index), y_lengths)
73  call apply_dimension_bounds(current_state%global_grid%size(x_index), current_state%parallel%dim_sizes(x_index), x_lengths)
74 
75  allocate(p_source(current_state%local_grid%size(z_index)-1, current_state%local_grid%size(y_index), &
76  current_state%local_grid%size(x_index)), prev_p(current_state%local_grid%size(z_index)-1, &
77  current_state%local_grid%size(y_index), current_state%local_grid%size(x_index)))
78 
79  cx=current_state%global_grid%configuration%horizontal%cx
80  cy=current_state%global_grid%configuration%horizontal%cy
81  allocate(rdzn(current_state%local_grid%size(z_index)-1), rdz(current_state%local_grid%size(z_index)-1), &
82  rho(current_state%local_grid%size(z_index)-1), rhon(current_state%local_grid%size(z_index)-1), &
83  dz(current_state%local_grid%size(z_index)-1), dzn(current_state%local_grid%size(z_index)-1))
84  rdzn=current_state%global_grid%configuration%vertical%rdzn(2:)
85  rdz=current_state%global_grid%configuration%vertical%rdz(2:)
86  rho=current_state%global_grid%configuration%vertical%rho(2:)
87  rhon=current_state%global_grid%configuration%vertical%rhon(2:)
88  dz=current_state%global_grid%configuration%vertical%dz(2:)
89  dzn=current_state%global_grid%configuration%vertical%dzn(2:)
90 
91  z_start=current_state%local_grid%halo_size(z_index)+2
92  z_end=current_state%local_grid%halo_size(z_index)+current_state%local_grid%size(z_index)
93  y_start=current_state%local_grid%halo_size(y_index)+1
94  y_end=current_state%local_grid%halo_size(y_index)+current_state%local_grid%size(y_index)
95  x_start=current_state%local_grid%halo_size(x_index)+1
96  x_end=current_state%local_grid%halo_size(x_index)+current_state%local_grid%size(x_index)
97 
98  y_rank_val = current_state%parallel%my_rank / current_state%parallel%dim_sizes(x_index)
99  x_rank_val = mod(current_state%parallel%my_rank, current_state%parallel%dim_sizes(x_index))
100  my_transposed_rank = x_rank_val*current_state%parallel%dim_sizes(y_index) + y_rank_val
101 
102  call mpi_comm_split(current_state%parallel%monc_communicator, 1, my_transposed_rank, new_communicator, ierr)
103  petsc_comm_world = new_communicator
104 
105  call petscinitialize(petsc_null_character, ierr)
106  call kspcreate(petsc_comm_world, ksp, ierr)
107  call dmdacreate3d(petsc_comm_world, dm_boundary_none, dm_boundary_periodic, dm_boundary_periodic, dmda_stencil_star, &
108  current_state%global_grid%size(z_index)-1, current_state%global_grid%size(y_index), &
109  current_state%global_grid%size(x_index), 1, current_state%parallel%dim_sizes(y_index), &
110  current_state%parallel%dim_sizes(x_index), 1, 1, (/ current_state%global_grid%size(z_index)-1 /), &
111  y_lengths, x_lengths, da, ierr)
112  call kspsetdm(ksp, da, ierr)
113  call kspsetcomputerhs(ksp, compute_rhs, petsc_null_object, ierr)
114  call kspsetcomputeoperators(ksp, compute_matrix, petsc_null_object, ierr)
115  call kspsetcomputeinitialguess(ksp, compute_initial_guess, petsc_null_object, ierr)
116  call petscoptionssetvalue("-options_left", "no", ierr)
117  if (trim(options_get_string(current_state%options_database, "solver_type")) .ne. "auto") then
118  call petscoptionssetvalue("-ksp_type", trim(options_get_string(current_state%options_database, "solver_type")), ierr)
119  end if
120  if (trim(options_get_string(current_state%options_database, "preconditioner_type")) .ne. "auto") then
121  call petscoptionssetvalue("-pc_type", trim(options_get_string(current_state%options_database, "preconditioner_type")), ierr)
122  end if
123  if (trim(options_get_string(current_state%options_database, "norm_type")) .ne. "auto") then
124  if (trim(options_get_string(current_state%options_database, "norm_type")) .eq. "preconditioned" .or. &
125  trim(options_get_string(current_state%options_database, "norm_type")) .eq. "unpreconditioned" .or. &
126  trim(options_get_string(current_state%options_database, "norm_type")) .eq. "natural" .or. &
127  trim(options_get_string(current_state%options_database, "norm_type")) .eq. "none") then
128  call petscoptionssetvalue("-ksp_norm_type", trim(options_get_string(current_state%options_database, "norm_type")), ierr)
129  else
130  call log_master_log(log_error, "Configured PETSc norm type of '"//&
131  trim(options_get_string(current_state%options_database, "norm_type"))//"' not recognised")
132  end if
133  end if
134  call petscoptionssetvalue("-ksp_rtol", conv_to_string(options_get_real(current_state%options_database, "tolerance")), ierr)
135  if (options_get_integer(current_state%options_database, "max_iterations") .gt. 0) then
136  call petscoptionssetvalue("-ksp_max_it", &
137  conv_to_string(options_get_integer(current_state%options_database, "max_iterations")), ierr)
138  end if
139  call kspsetfromoptions(ksp, ierr)
140  call kspsetinitialguessnonzero(ksp, petsc_true, ierr)
141 
142  if (log_is_master() .and. log_get_logging_level() == log_debug) then
143  call kspmonitorset(ksp,ksp_monitor,petsc_null_object, petsc_null_function,ierr)
144  end if
145  prev_p=0.0_default_precision
146  call init_halo_communication(current_state, get_single_field_per_halo_cell, halo_swap_state, 1, .false.)
147  call kspgettype(ksp, ksp_type, ierr)
148  call kspgetpc(ksp, pc_instance, ierr)
149  call pcgettype(pc_instance, pc_type, ierr)
150  call log_master_log(log_info, "PETSc iterative solver initialised, using "//trim(pc_type)//" preconditioner with "//&
151  trim(ksp_type)//" solver")
152  end subroutine init_callback
153 
160  subroutine ksp_monitor(ksp, n, rnorm, dummy, ierr)
161  ksp ksp
162  petscerrorcode ierr
163  petscint n,dummy
164  petscreal rnorm
165 
166  call log_log(log_debug, "Iteration="//trim(conv_to_string(n))//" Rnorm="//trim(conv_to_string(rnorm, &
167  exponent_small_numbers=.true.)))
168  end subroutine ksp_monitor
169 
174  subroutine timestep_callback(current_state)
175  type(model_state_type), target, intent(inout) :: current_state
176 
177  petscerrorcode :: ierr
178  vec x
179  petscscalar, pointer :: xx(:)
180  integer :: its, i, j, k
181  petscreal :: rnorm
182  kspconvergedreason :: reason
183 
184  call complete_psrce_calculation(current_state, current_state%local_grid%halo_size(y_index), &
185  current_state%local_grid%halo_size(x_index))
186 
187  p_source=current_state%p%data(z_start:z_end, y_start:y_end, x_start:x_end)
188  call kspsolve(ksp, petsc_null_object, petsc_null_object, ierr)
189  call kspgetsolution(ksp, x, ierr)
190  call vecgetarrayreadf90(x, xx, ierr)
191 
192  call copy_petsc_pointer_to_data(xx, z_start, z_end, y_start, y_end, x_start, x_end, current_state%p%data)
193  call vecrestorearrayreadf90(x, xx, ierr)
194 
195  prev_p=current_state%p%data(z_start:z_end, y_start:y_end, x_start:x_end)
196 
197  if (log_is_master() .and. log_get_logging_level() == log_debug) then
198  call kspgetiterationnumber(ksp, its, ierr)
199  call kspgetresidualnorm(ksp, rnorm, ierr)
200  call kspgetconvergedreason(ksp, reason, ierr)
201  call log_log(log_debug, "Converged in "//trim(conv_to_string(its))//" rnorm="//trim(conv_to_string(&
202  rnorm, exponent_small_numbers=.true.))// " ("//trim(determine_convegence_reason(reason))//")")
203  end if
204  call blocking_halo_swap(current_state, halo_swap_state, copy_p_to_halo_buffer, &
206  end subroutine timestep_callback
207 
208  character(len=STRING_LENGTH) function determine_convegence_reason(r_code)
209  integer, intent(in) :: r_code
210 
211  if (r_code == 1 .or. r_code == 2) then
212  determine_convegence_reason="relative tolerance of residual norm"
213  else if (r_code == 9 .or. r_code == 3) then
214  determine_convegence_reason="residual norm less than absolute tolerance"
215  else if (r_code == 4) then
216  determine_convegence_reason="number of iterations exceeded maximum"
217  else if (r_code == -3) then
218  determine_convegence_reason="diverged as number of iterations exceeded maximum before any convergence criteria"
219  else if (r_code == -4) then
220  determine_convegence_reason="diverged as divergence tolerance exceeded"
221  else if (r_code .gt. 0) then
222  determine_convegence_reason="convergence code of "//conv_to_string(r_code)
223  else if (r_code .lt. 0) then
224  determine_convegence_reason="divergence code of "//conv_to_string(r_code)
225  end if
226  end function determine_convegence_reason
227 
234  subroutine compute_initial_guess(ksp, x, dummy, ierr)
235  petscerrorcode :: ierr
236  ksp :: ksp
237  vec :: x
238  integer :: dummy(*)
239 
240  dm dm
241  petscscalar, pointer :: xx(:)
242  petscint :: zs, ys, xs, zm, ym, xm
243 
244  call kspgetdm(ksp, dm, ierr)
245  call dmdagetcorners(dm, zs, ys, xs, zm, ym, xm, ierr)
246  call vecgetarrayf90(x, xx, ierr)
247  call copy_data_to_petsc_pointer(xx, zs, ys, xs, zm, ym, xm, prev_p)
248  call vecrestorearrayf90(x, xx, ierr)
249  end subroutine compute_initial_guess
250 
256  subroutine compute_rhs(ksp, b, dummy, ierr)
257  petscerrorcode :: ierr
258  ksp :: ksp
259  vec :: b
260  integer :: dummy(*)
261 
262  dm dm
263  petscscalar, pointer :: xx(:)
264  petscint :: zs, ys, xs, zm, ym, xm
265 
266  call kspgetdm(ksp, dm, ierr)
267  call dmdagetcorners(dm, zs, ys, xs, zm, ym, xm, ierr)
268  call vecgetarrayf90(b, xx, ierr)
269  call copy_data_to_petsc_pointer(xx, zs, ys, xs, zm, ym, xm, p_source)
270  call vecrestorearrayf90(b, xx, ierr)
271  end subroutine compute_rhs
272 
283  subroutine copy_data_to_petsc_pointer(x, zs, ys, xs, zm, ym, xm, src_values)
284  integer, intent(in) :: zs, ys, xs, zm, ym, xm
285  petscscalar, intent(inout) :: x(zs:zs+zm-1, ys:ys+ym-1, xs:xs+xm-1)
286  real(kind=DEFAULT_PRECISION), dimension(:,:,:), intent(in) :: src_values
287 
288  integer :: i, j, k
289 
290  do i=xs, xs+xm-1
291  do j=ys, ys+ym-1
292  do k=zs, zs+zm-1
293  x(k, j, i)=src_values((k-zs)+1, (j-ys)+1, (i-xs)+1)
294  end do
295  end do
296  end do
297  end subroutine copy_data_to_petsc_pointer
298 
309  subroutine copy_petsc_pointer_to_data(x, z_start_idx, z_end_idx, y_start_idx, y_end_idx, x_start_idx, x_end_idx, target_values)
310  integer, intent(in) :: z_start_idx, z_end_idx, y_start_idx, y_end_idx, x_start_idx, x_end_idx
311  petscscalar :: x((z_end_idx-z_start_idx)+1, (y_end_idx-y_start_idx)+1, (x_end_idx-x_start_idx)+1)
312  real(kind=DEFAULT_PRECISION), dimension(:,:,:), intent(inout) :: target_values
313 
314  target_values(z_start_idx:z_end_idx, y_start_idx:y_end_idx, x_start_idx:x_end_idx)=x
315  end subroutine copy_petsc_pointer_to_data
316 
323  subroutine compute_matrix(ksp, A, B, dummy, ierr)
324  petscerrorcode :: ierr
325  ksp :: ksp
326  mat :: a, b
327  integer :: dummy(*)
328 
329  dm dm
330  petscint :: zs, ys,xs, zm, ym, xm, mz, my, mx
331  real(kind=DEFAULT_PRECISION) :: v(7), Hx, Hy
332  real(kind=DEFAULT_PRECISION), dimension(:), allocatable :: HzU, HzD, d_sc
333  matstencil :: row(4),col(4,7)
334  integer :: i, j, k, num
335 
336  call kspgetdm(ksp, dm, ierr)
337  call dmdagetinfo(dm,petsc_null_integer, mz, my, mx, petsc_null_integer, petsc_null_integer, petsc_null_integer, &
338  petsc_null_integer, petsc_null_integer, petsc_null_integer, petsc_null_integer, petsc_null_integer, petsc_null_integer, ierr)
339  call dmdagetcorners(dm, zs, ys, xs, zm, ym, xm, ierr)
340 
341  allocate(hzu(0:mz-1), hzd(0:mz-1), d_sc(0:mz-1))
342 
343  do k=0, mz-1
344  d_sc(k)=rdz(k+1) / rhon(k+1)
345  if (k .gt. 0) then
346  hzd(k)=rho(k) * rdzn(k+1)
347  else
348  hzd(k)=0.0_default_precision
349  end if
350  if (k .lt. mz-1) then
351  hzu(k)=rho(k+1) * rdzn(k+2)
352  else
353  hzu(k)=0.0_default_precision
354  end if
355  end do
356 
357  hx = cx * cx
358  hy = cy * cy
359  do i=xs, xs+xm-1
360  do j=ys,ys+ym-1
361  do k=zs, zs+zm-1
362  row(matstencil_i) = k
363  row(matstencil_j) = j
364  row(matstencil_k) = i
365 
366  v(1)=hy
367  col(matstencil_i, 1)=k
368  col(matstencil_j, 1)=j-1
369  col(matstencil_k, 1)=i
370  v(2)=hx
371  col(matstencil_i, 2)=k
372  col(matstencil_j, 2)=j
373  col(matstencil_k, 2)=i-1
374  v(3)=d_sc(k) * (-(hzu(k) + hzd(k))) - (2.0*(hx + hy))
375  col(matstencil_i, 3)=k
376  col(matstencil_j, 3)=j
377  col(matstencil_k, 3)=i
378  v(4)=hx
379  col(matstencil_i, 4)=k
380  col(matstencil_j, 4)=j
381  col(matstencil_k, 4)=i+1
382  v(5)=hy
383  col(matstencil_i, 5)=k
384  col(matstencil_j, 5)=j+1
385  col(matstencil_k, 5)=i
386  num=6
387  if (k .gt. zs) then
388  v(num)=(d_sc(k)*hzd(k))
389  col(matstencil_i, num)=k-1
390  col(matstencil_j, num)=j
391  col(matstencil_k, num)=i
392  num=num+1
393  end if
394  if (k .lt. mz-1) then
395  v(num)=(d_sc(k)*hzu(k))
396  col(matstencil_i, num)=k+1
397  col(matstencil_j, num)=j
398  col(matstencil_k, num)=i
399  num=num+1
400  end if
401  call matsetvaluesstencil(b, 1, row, num-1, col, v, insert_values, ierr)
402  end do
403  end do
404  end do
405  call matassemblybegin(b, mat_final_assembly, ierr)
406  call matassemblyend(b, mat_final_assembly, ierr)
407  if ( a .ne. b) then
408  call matassemblybegin(a, mat_final_assembly, ierr)
409  call matassemblyend(a, mat_final_assembly, ierr)
410  endif
411  deallocate(hzu, hzd, d_sc)
412  end subroutine compute_matrix
413 
418  subroutine apply_dimension_bounds(dim_size, dim_processes, length_array)
419  integer, intent(in) :: dim_size, dim_processes
420  integer, intent(out) :: length_array(:)
421 
422  integer :: i, dimension_division, dimension_extra
423 
424  dimension_division = dim_size / dim_processes
425  length_array= dimension_division
426 
427  dimension_extra = dim_size - (dimension_division * dim_processes)
428  if (dimension_extra .gt. 0) then
429  do i=1, dimension_extra
430  length_array(i)=length_array(i)+1
431  end do
432  end if
433  end subroutine apply_dimension_bounds
434 
440  subroutine complete_psrce_calculation(current_state, y_halo_size, x_halo_size)
441  type(model_state_type), target, intent(inout) :: current_state
442  integer, intent(in) :: y_halo_size, x_halo_size
443 
444  integer :: ierr, combined_handles(2), i, j, k
445 
446  combined_handles(1)=current_state%psrce_x_hs_recv_request
447  combined_handles(2)=current_state%psrce_y_hs_recv_request
448  call mpi_waitall(2, combined_handles, mpi_statuses_ignore, ierr)
449 
450  do j=current_state%local_grid%local_domain_start_index(y_index), current_state%local_grid%local_domain_end_index(y_index)
451  do k=2,current_state%local_grid%size(z_index)
452 #ifdef U_ACTIVE
453  current_state%p%data(k,j,x_halo_size+1)=current_state%p%data(k,j,x_halo_size+1)-&
454  current_state%psrce_recv_buffer_x(k-1,j-x_halo_size)
455 #endif
456 #ifdef V_ACTIVE
457  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)-&
458  current_state%global_grid%configuration%horizontal%cy * current_state%sv%data(k, j-1, x_halo_size+1)
459 #endif
460  end do
461  end do
462 
463 #ifdef V_ACTIVE
464  do i=current_state%local_grid%local_domain_start_index(x_index), current_state%local_grid%local_domain_end_index(x_index)
465  do k=2,current_state%local_grid%size(z_index)
466  current_state%p%data(k,y_halo_size+1,i)=current_state%p%data(k,y_halo_size+1,i)-&
467  current_state%psrce_recv_buffer_y(k-1,i-y_halo_size)
468  end do
469  end do
470 #endif
471 
472  combined_handles(1)=current_state%psrce_x_hs_send_request
473  combined_handles(2)=current_state%psrce_y_hs_send_request
474  call mpi_waitall(2, combined_handles, mpi_statuses_ignore, ierr)
475  end subroutine complete_psrce_calculation
476 
485  subroutine copy_p_to_halo_buffer(current_state, neighbour_description, dim, source_index, &
486  pid_location, current_page, source_data)
487  type(model_state_type), intent(inout) :: current_state
488  integer, intent(in) :: dim, pid_location, source_index
489  integer, intent(inout) :: current_page(:)
490  type(neighbour_description_type), intent(inout) :: neighbour_description
491  type(field_data_wrapper_type), dimension(:), intent(in), optional :: source_data
492 
493  call copy_field_to_buffer(current_state%local_grid, neighbour_description%send_halo_buffer, current_state%p%data, &
494  dim, source_index, current_page(pid_location))
495 
496  current_page(pid_location)=current_page(pid_location)+1
497  end subroutine copy_p_to_halo_buffer
498 
499  !! @param dim The dimension we receive for
500  !! @param target_index The target index for the dimension we are receiving for
501  !! @param neighbour_location The location in the local neighbour data stores of this neighbour
502  !! @param current_page The current, next, halo swap page to read from (all previous have been read and copied already)
503  !! @param source_data Optional source data which is written into
504  subroutine copy_halo_buffer_to_p(current_state, neighbour_description, dim, target_index, &
505  neighbour_location, current_page, source_data)
506  type(model_state_type), intent(inout) :: current_state
507  integer, intent(in) :: dim, target_index, neighbour_location
508  integer, intent(inout) :: current_page(:)
509  type(neighbour_description_type), intent(inout) :: neighbour_description
510  type(field_data_wrapper_type), dimension(:), intent(in), optional :: source_data
511 
512  call copy_buffer_to_field(current_state%local_grid, neighbour_description%recv_halo_buffer, current_state%p%data, &
513  dim, target_index, current_page(neighbour_location))
514 
515  current_page(neighbour_location)=current_page(neighbour_location)+1
516  end subroutine copy_halo_buffer_to_p
517 
521  subroutine perform_local_data_copy_for_p(current_state, halo_depth, involve_corners, source_data)
522  type(model_state_type), intent(inout) :: current_state
523  integer, intent(in) :: halo_depth
524  logical, intent(in) :: involve_corners
525  type(field_data_wrapper_type), dimension(:), intent(in), optional :: source_data
526 
527  call perform_local_data_copy_for_field(current_state%p%data, current_state%local_grid, &
528  current_state%parallel%my_rank, halo_depth, involve_corners)
529  end subroutine perform_local_data_copy_for_p
530 end module petsc_solver_mod
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...
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...
character(len=string_length) function determine_convegence_reason(r_code)
real(kind=default_precision), dimension(:), allocatable rdz
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.
type(halo_communication_type), save halo_swap_state
subroutine perform_local_data_copy_for_p(current_state, halo_depth, involve_corners, source_data)
Does local data copying for P variable halo swap.
real(kind=default_precision), dimension(:), allocatable rho
integer, parameter, public log_error
Only log ERROR messages.
Definition: logging.F90:11
subroutine copy_petsc_pointer_to_data(x, z_start_idx, z_end_idx, y_start_idx, y_end_idx, x_start_idx, x_end_idx, target_values)
Copies the data in a pointer that was provided by PETSc into some target data, doing it this way mean...
real(kind=default_precision), dimension(:), allocatable rhon
Contains the types used for communication, holding the state of communications and supporting activit...
character(len=string_length) function, public options_get_string(options_database, key, index)
Retrieves a string value from the database that matches the provided key.
PETSc solver component to call out to PETSc for solving the Poisson equation for pressure.
Definition: petsc_solver.F90:6
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...
Logging utility.
Definition: logging.F90:2
integer, parameter, public default_precision
MPI communication type which we use for the prognostic and calculation data.
Definition: datadefn.F90:17
integer, parameter, public z_index
Grid index parameters.
Definition: grids.F90:14
real(kind=default_precision), dimension(:), allocatable dz
real(kind=default_precision), dimension(:,:,:), allocatable p_source
Contains common definitions for the data and datatypes used by MONC.
Definition: datadefn.F90:2
The ModelState which represents the current state of a run.
Definition: state.F90:39
subroutine, public log_master_log(level, message)
Will log just from the master process.
Definition: logging.F90:47
integer, parameter, public log_debug
Log DEBUG, INFO, WARNING and ERROR messages.
Definition: logging.F90:14
subroutine copy_halo_buffer_to_p(current_state, neighbour_description, dim, target_index, neighbour_location, current_page, source_data)
Conversion between common inbuilt FORTRAN data types.
Definition: conversions.F90:5
real(kind=default_precision), dimension(:), allocatable dzn
Converts data types to strings.
Definition: conversions.F90:36
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...
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...
Definition: logging.F90:75
subroutine copy_data_to_petsc_pointer(x, zs, ys, xs, zm, ym, xm, src_values)
Copies data into a data pointer which is provided by PETSc, doing it this ways allows us to give a sh...
Maintains the state of a halo swap and contains buffers, neighbours etc.
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...
subroutine compute_matrix(ksp, A, B, dummy, ierr)
Call back issued from within PETSc to create the matrix, this is only called once (the first PETSc ru...
Interfaces and types that MONC components must specify.
Defined the local grid, i.e. the grid held on this process after decomposition.
Definition: grids.F90:111
real(kind=default_precision), dimension(:,:,:), allocatable prev_p
subroutine init_callback(current_state)
Called upon model initialisation. Will basically read from the options database and set options in th...
real(kind=default_precision) cy
Provides the mechanism for halo swapping. This module contains the functionality required to determin...
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...
Describes the neighbours of a process in a specific dimension and contains the communication buffers ...
integer, parameter, public string_length
Default length of strings.
Definition: datadefn.F90:10
subroutine compute_rhs(ksp, b, dummy, ierr)
Callback issued from the PETSc library to compute the RHS, this is called every timestep (as we have ...
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 timestep_callback(current_state)
Timestep hook which is called at each timestep to solve the pressure equation via PETSc...
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.
Functionality to support the different types of grid and abstraction between global grids and local o...
Definition: grids.F90:5
subroutine apply_dimension_bounds(dim_size, dim_processes, length_array)
Applies dimension bounds to determine the number of elements held locally for each process in that di...
type(component_descriptor_type) function, public petsc_solver_get_descriptor()
Provides the descriptor back to the caller and is used in component registration. ...
logical function, public log_is_master()
Determines whether the process is the master logging process. This might be preferable rather than ca...
Definition: logging.F90:66
integer function, public options_get_integer(options_database, key, index)
Retrieves an integer value from the database that matches the provided key.
subroutine finalisation_callback(current_state)
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...
integer, parameter, public log_info
Log INFO, WARNING and ERROR messages.
Definition: logging.F90:13
real(kind=default_precision), dimension(:), allocatable rdzn
The model state which represents the current state of a run.
Definition: state.F90:2
integer function, public log_get_logging_level()
Retrieves the current logging level.
Definition: logging.F90:122
integer, parameter, public y_index
Definition: grids.F90:14
subroutine ksp_monitor(ksp, n, rnorm, dummy, ierr)
Monitor procedure called on each iteration, this is provided only at debugging level.
integer, parameter, public x_index
Definition: grids.F90:14
subroutine compute_initial_guess(ksp, x, dummy, ierr)
Determines the initial guess, this is called from within PETSc and sets it to be the last value of P ...
real(kind=default_precision) cx