7 use mom_coms,
only : broadcast, sum_across_pes, min_across_pes, max_across_pes
14 use mpp_domains_mod,
only : mpp_define_layout, mpp_get_boundary
15 use mpp_domains_mod,
only : mom_define_io_domain => mpp_define_io_domain
16 use mpp_domains_mod,
only : mom_define_domain => mpp_define_domains
17 use mpp_domains_mod,
only : domain2d, domain1d, mpp_get_data_domain
18 use mpp_domains_mod,
only : mpp_get_compute_domain, mpp_get_global_domain
19 use mpp_domains_mod,
only : global_field_sum => mpp_global_sum
20 use mpp_domains_mod,
only : mpp_update_domains, cyclic_global_domain, fold_north_edge
21 use mpp_domains_mod,
only : mpp_start_update_domains, mpp_complete_update_domains
22 use mpp_domains_mod,
only : mpp_create_group_update, mpp_do_group_update
23 use mpp_domains_mod,
only : group_pass_type => mpp_group_update_type
24 use mpp_domains_mod,
only : mpp_reset_group_update_field
25 use mpp_domains_mod,
only : mpp_group_update_initialized
26 use mpp_domains_mod,
only : mpp_start_group_update, mpp_complete_group_update
27 use mpp_domains_mod,
only : compute_block_extent => mpp_compute_block_extent
28 use mpp_parameter_mod,
only : agrid, bgrid_ne, cgrid_ne, scalar_pair, bitwise_exact_sum, corner
29 use mpp_parameter_mod,
only : to_east => wupdate, to_west => eupdate, omit_corners => edgeupdate
30 use mpp_parameter_mod,
only : to_north => supdate, to_south => nupdate, center
31 use fms_io_mod,
only : file_exist, parse_mask_table
33 implicit none ;
private
40 public :: global_field_sum, sum_across_pes, min_across_pes, max_across_pes
41 public :: agrid, bgrid_ne, cgrid_ne, scalar_pair, bitwise_exact_sum, corner, center
42 public :: to_east, to_west, to_north, to_south,
to_all, omit_corners
100 type(domain2d),
pointer :: mpp_domain => null()
102 type(domain2d),
pointer :: mpp_domain_d2 => null()
110 logical :: nonblocking_updates
112 logical :: thin_halo_updates
119 integer :: io_layout(2)
124 logical,
pointer :: maskmap(:,:) => null()
132 integer,
parameter ::
to_all = to_east + to_west + to_north + to_south
137 subroutine pass_var_3d(array, MOM_dom, sideflag, complete, position, halo, &
139 real,
dimension(:,:,:),
intent(inout) :: array
144 integer,
optional,
intent(in) :: sideflag
148 logical,
optional,
intent(in) :: complete
152 integer,
optional,
intent(in) :: position
155 integer,
optional,
intent(in) :: halo
157 integer,
optional,
intent(in) :: clock
161 logical :: block_til_complete
163 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
166 if (
present(sideflag))
then ;
if (sideflag > 0) dirflag = sideflag ;
endif
167 block_til_complete = .true.
168 if (
present(complete)) block_til_complete = complete
170 if (
present(halo) .and. mom_dom%thin_halo_updates)
then
171 call mpp_update_domains(array, mom_dom%mpp_domain, flags=dirflag, &
172 complete=block_til_complete, position=position, &
173 whalo=halo, ehalo=halo, shalo=halo, nhalo=halo)
175 call mpp_update_domains(array, mom_dom%mpp_domain, flags=dirflag, &
176 complete=block_til_complete, position=position)
179 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
184 subroutine pass_var_2d(array, MOM_dom, sideflag, complete, position, halo, inner_halo, clock)
185 real,
dimension(:,:),
intent(inout) :: array
189 integer,
optional,
intent(in) :: sideflag
193 logical,
optional,
intent(in) :: complete
197 integer,
optional,
intent(in) :: position
200 integer,
optional,
intent(in) :: halo
202 integer,
optional,
intent(in) :: inner_halo
206 integer,
optional,
intent(in) :: clock
210 real,
allocatable,
dimension(:,:) :: tmp
211 integer :: pos, i_halo, j_halo
212 integer :: isc, iec, jsc, jec, isd, ied, jsd, jed, IscB, IecB, JscB, JecB
213 integer :: inner, i, j, isfw, iefw, isfe, iefe, jsfs, jefs, jsfn, jefn
215 logical :: block_til_complete
217 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
220 if (
present(sideflag))
then ;
if (sideflag > 0) dirflag = sideflag ;
endif
221 block_til_complete = .true. ;
if (
present(complete)) block_til_complete = complete
222 pos = center ;
if (
present(position)) pos = position
224 if (
present(inner_halo))
then ;
if (inner_halo >= 0)
then
226 allocate(tmp(
size(array,1),
size(array,2)))
227 tmp(:,:) = array(:,:)
228 block_til_complete = .true.
231 if (
present(halo) .and. mom_dom%thin_halo_updates)
then
232 call mpp_update_domains(array, mom_dom%mpp_domain, flags=dirflag, &
233 complete=block_til_complete, position=position, &
234 whalo=halo, ehalo=halo, shalo=halo, nhalo=halo)
236 call mpp_update_domains(array, mom_dom%mpp_domain, flags=dirflag, &
237 complete=block_til_complete, position=position)
240 if (
present(inner_halo))
then ;
if (inner_halo >= 0)
then
241 call mpp_get_compute_domain(mom_dom%mpp_domain, isc, iec, jsc, jec)
242 call mpp_get_data_domain(mom_dom%mpp_domain, isd, ied, jsd, jed)
244 isc = isc - (isd-1) ; iec = iec - (isd-1) ; ied = ied - (isd-1) ; isd = 1
245 jsc = jsc - (jsd-1) ; jec = jec - (jsd-1) ; jed = jed - (jsd-1) ; jsd = 1
246 i_halo = min(inner_halo, isc-1) ; j_halo = min(inner_halo, jsc-1)
249 if (pos == center)
then
250 if (
size(array,1) == ied)
then
251 isfw = isc - i_halo ; iefw = isc ; isfe = iec ; iefe = iec + i_halo
252 else ;
call mom_error(fatal,
"pass_var_2d: wrong i-size for CENTER array.") ;
endif
253 if (
size(array,2) == jed)
then
254 isfw = isc - i_halo ; iefw = isc ; isfe = iec ; iefe = iec + i_halo
255 else ;
call mom_error(fatal,
"pass_var_2d: wrong j-size for CENTER array.") ;
endif
256 elseif (pos == corner)
then
257 if (
size(array,1) == ied)
then
258 isfw = max(isc - (i_halo+1), 1) ; iefw = isc ; isfe = iec ; iefe = iec + i_halo
259 elseif (
size(array,1) == ied+1)
then
260 isfw = isc - i_halo ; iefw = isc+1 ; isfe = iec+1 ; iefe = min(iec + 1 + i_halo, ied+1)
261 else ;
call mom_error(fatal,
"pass_var_2d: wrong i-size for CORNER array.") ;
endif
262 if (
size(array,2) == jed)
then
263 jsfs = max(jsc - (j_halo+1), 1) ; jefs = jsc ; jsfn = jec ; jefn = jec + j_halo
264 elseif (
size(array,2) == jed+1)
then
265 jsfs = jsc - j_halo ; jefs = jsc+1 ; jsfn = jec+1 ; jefn = min(jec + 1 + j_halo, jed+1)
266 else ;
call mom_error(fatal,
"pass_var_2d: wrong j-size for CORNER array.") ;
endif
268 call mom_error(fatal,
"pass_var_2d: Unrecognized position")
272 do j=jsfs,jefn ;
do i=isfw,iefw ; array(i,j) = tmp(i,j) ;
enddo ;
enddo
273 do j=jsfs,jefn ;
do i=isfe,iefe ; array(i,j) = tmp(i,j) ;
enddo ;
enddo
274 do j=jsfs,jefs ;
do i=isfw,iefe ; array(i,j) = tmp(i,j) ;
enddo ;
enddo
275 do j=jsfn,jefn ;
do i=isfw,iefe ; array(i,j) = tmp(i,j) ;
enddo ;
enddo
280 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
287 real,
dimension(:,:),
intent(inout) :: array
292 integer,
optional,
intent(in) :: sideflag
296 integer,
optional,
intent(in) :: position
299 logical,
optional,
intent(in) :: complete
303 integer,
optional,
intent(in) :: halo
305 integer,
optional,
intent(in) :: clock
311 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
314 if (
present(sideflag))
then ;
if (sideflag > 0) dirflag = sideflag ;
endif
316 if (
present(halo) .and. mom_dom%thin_halo_updates)
then
318 flags=dirflag, position=position, &
319 whalo=halo, ehalo=halo, shalo=halo, nhalo=halo)
322 flags=dirflag, position=position)
325 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
332 real,
dimension(:,:,:),
intent(inout) :: array
337 integer,
optional,
intent(in) :: sideflag
341 integer,
optional,
intent(in) :: position
344 logical,
optional,
intent(in) :: complete
348 integer,
optional,
intent(in) :: halo
350 integer,
optional,
intent(in) :: clock
356 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
359 if (
present(sideflag))
then ;
if (sideflag > 0) dirflag = sideflag ;
endif
361 if (
present(halo) .and. mom_dom%thin_halo_updates)
then
363 flags=dirflag, position=position, &
364 whalo=halo, ehalo=halo, shalo=halo, nhalo=halo)
367 flags=dirflag, position=position)
370 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
377 integer,
intent(in) :: id_update
380 real,
dimension(:,:),
intent(inout) :: array
385 integer,
optional,
intent(in) :: sideflag
389 integer,
optional,
intent(in) :: position
392 integer,
optional,
intent(in) :: halo
394 integer,
optional,
intent(in) :: clock
399 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
402 if (
present(sideflag))
then ;
if (sideflag > 0) dirflag = sideflag ;
endif
404 if (
present(halo) .and. mom_dom%thin_halo_updates)
then
405 call mpp_complete_update_domains(id_update, array, mom_dom%mpp_domain, &
406 flags=dirflag, position=position, &
407 whalo=halo, ehalo=halo, shalo=halo, nhalo=halo)
409 call mpp_complete_update_domains(id_update, array, mom_dom%mpp_domain, &
410 flags=dirflag, position=position)
413 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
420 integer,
intent(in) :: id_update
423 real,
dimension(:,:,:),
intent(inout) :: array
428 integer,
optional,
intent(in) :: sideflag
432 integer,
optional,
intent(in) :: position
435 integer,
optional,
intent(in) :: halo
437 integer,
optional,
intent(in) :: clock
442 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
445 if (
present(sideflag))
then ;
if (sideflag > 0) dirflag = sideflag ;
endif
447 if (
present(halo) .and. mom_dom%thin_halo_updates)
then
448 call mpp_complete_update_domains(id_update, array, mom_dom%mpp_domain, &
449 flags=dirflag, position=position, &
450 whalo=halo, ehalo=halo, shalo=halo, nhalo=halo)
452 call mpp_complete_update_domains(id_update, array, mom_dom%mpp_domain, &
453 flags=dirflag, position=position)
456 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
462 subroutine pass_vector_2d(u_cmpt, v_cmpt, MOM_dom, direction, stagger, complete, halo, &
464 real,
dimension(:,:),
intent(inout) :: u_cmpt
467 real,
dimension(:,:),
intent(inout) :: v_cmpt
473 integer,
optional,
intent(in) :: direction
479 integer,
optional,
intent(in) :: stagger
482 logical,
optional,
intent(in) :: complete
485 integer,
optional,
intent(in) :: halo
487 integer,
optional,
intent(in) :: clock
491 integer :: stagger_local
493 logical :: block_til_complete
495 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
497 stagger_local = cgrid_ne
498 if (
present(stagger)) stagger_local = stagger
501 if (
present(direction))
then ;
if (direction > 0) dirflag = direction ;
endif
502 block_til_complete = .true.
503 if (
present(complete)) block_til_complete = complete
505 if (
present(halo) .and. mom_dom%thin_halo_updates)
then
506 call mpp_update_domains(u_cmpt, v_cmpt, mom_dom%mpp_domain, flags=dirflag, &
507 gridtype=stagger_local, complete = block_til_complete, &
508 whalo=halo, ehalo=halo, shalo=halo, nhalo=halo)
510 call mpp_update_domains(u_cmpt, v_cmpt, mom_dom%mpp_domain, flags=dirflag, &
511 gridtype=stagger_local, complete = block_til_complete)
514 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
525 real,
dimension(:,:),
intent(inout) :: u_cmpt
528 real,
dimension(:,:),
intent(inout) :: v_cmpt
534 integer,
optional,
intent(in) :: stagger
537 logical,
optional,
intent(in) :: scalar
538 integer,
optional,
intent(in) :: clock
542 integer :: stagger_local
544 integer :: i, j, isc, iec, jsc, jec, isd, ied, jsd, jed, IscB, IecB, JscB, JecB
545 real,
allocatable,
dimension(:) :: sbuff_x, sbuff_y, wbuff_x, wbuff_y
546 logical :: block_til_complete
548 if (.not. mom_dom%symmetric)
then
552 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
554 stagger_local = cgrid_ne
555 if (
present(stagger)) stagger_local = stagger
557 if (.not.(stagger_local == cgrid_ne .or. stagger_local == bgrid_ne))
return
559 call mpp_get_compute_domain(mom_dom%mpp_domain, isc, iec, jsc, jec)
560 call mpp_get_data_domain(mom_dom%mpp_domain, isd, ied, jsd, jed)
564 isc = isc - (isd-1) ; iec = iec - (isd-1)
565 jsc = jsc - (jsd-1) ; jec = jec - (jsd-1)
566 iscb = isc ; iecb = iec+1 ; jscb = jsc ; jecb = jec+1
569 if (
present(scalar))
then ;
if (scalar) dirflag =
to_all+scalar_pair ;
endif
571 if (stagger_local == cgrid_ne)
then
572 allocate(wbuff_x(jsc:jec)) ;
allocate(sbuff_y(isc:iec))
573 wbuff_x(:) = 0.0 ; sbuff_y(:) = 0.0
574 call mpp_get_boundary(u_cmpt, v_cmpt, mom_dom%mpp_domain, flags=dirflag, &
575 wbufferx=wbuff_x, sbuffery=sbuff_y, &
578 v_cmpt(i,jscb) = sbuff_y(i)
581 u_cmpt(iscb,j) = wbuff_x(j)
583 deallocate(wbuff_x) ;
deallocate(sbuff_y)
584 elseif (stagger_local == bgrid_ne)
then
585 allocate(wbuff_x(jscb:jecb)) ;
allocate(sbuff_x(iscb:iecb))
586 allocate(wbuff_y(jscb:jecb)) ;
allocate(sbuff_y(iscb:iecb))
587 wbuff_x(:) = 0.0 ; wbuff_y(:) = 0.0 ; sbuff_x(:) = 0.0 ; sbuff_y(:) = 0.0
588 call mpp_get_boundary(u_cmpt, v_cmpt, mom_dom%mpp_domain, flags=dirflag, &
589 wbufferx=wbuff_x, sbufferx=sbuff_x, &
590 wbuffery=wbuff_y, sbuffery=sbuff_y, &
593 u_cmpt(i,jscb) = sbuff_x(i) ; v_cmpt(i,jscb) = sbuff_y(i)
596 u_cmpt(iscb,j) = wbuff_x(j) ; v_cmpt(iscb,j) = wbuff_y(j)
598 deallocate(wbuff_x) ;
deallocate(sbuff_x)
599 deallocate(wbuff_y) ;
deallocate(sbuff_y)
602 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
608 subroutine pass_vector_3d(u_cmpt, v_cmpt, MOM_dom, direction, stagger, complete, halo, &
610 real,
dimension(:,:,:),
intent(inout) :: u_cmpt
613 real,
dimension(:,:,:),
intent(inout) :: v_cmpt
619 integer,
optional,
intent(in) :: direction
625 integer,
optional,
intent(in) :: stagger
628 logical,
optional,
intent(in) :: complete
631 integer,
optional,
intent(in) :: halo
633 integer,
optional,
intent(in) :: clock
637 integer :: stagger_local
639 logical :: block_til_complete
641 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
643 stagger_local = cgrid_ne
644 if (
present(stagger)) stagger_local = stagger
647 if (
present(direction))
then ;
if (direction > 0) dirflag = direction ;
endif
648 block_til_complete = .true.
649 if (
present(complete)) block_til_complete = complete
651 if (
present(halo) .and. mom_dom%thin_halo_updates)
then
652 call mpp_update_domains(u_cmpt, v_cmpt, mom_dom%mpp_domain, flags=dirflag, &
653 gridtype=stagger_local, complete = block_til_complete, &
654 whalo=halo, ehalo=halo, shalo=halo, nhalo=halo)
656 call mpp_update_domains(u_cmpt, v_cmpt, mom_dom%mpp_domain, flags=dirflag, &
657 gridtype=stagger_local, complete = block_til_complete)
660 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
668 real,
dimension(:,:),
intent(inout) :: u_cmpt
671 real,
dimension(:,:),
intent(inout) :: v_cmpt
677 integer,
optional,
intent(in) :: direction
683 integer,
optional,
intent(in) :: stagger
686 logical,
optional,
intent(in) :: complete
689 integer,
optional,
intent(in) :: halo
691 integer,
optional,
intent(in) :: clock
697 integer :: stagger_local
700 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
702 stagger_local = cgrid_ne
703 if (
present(stagger)) stagger_local = stagger
706 if (
present(direction))
then ;
if (direction > 0) dirflag = direction ;
endif
708 if (
present(halo) .and. mom_dom%thin_halo_updates)
then
710 mom_dom%mpp_domain, flags=dirflag, gridtype=stagger_local, &
711 whalo=halo, ehalo=halo, shalo=halo, nhalo=halo)
714 mom_dom%mpp_domain, flags=dirflag, gridtype=stagger_local)
717 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
725 real,
dimension(:,:,:),
intent(inout) :: u_cmpt
728 real,
dimension(:,:,:),
intent(inout) :: v_cmpt
734 integer,
optional,
intent(in) :: direction
740 integer,
optional,
intent(in) :: stagger
743 logical,
optional,
intent(in) :: complete
746 integer,
optional,
intent(in) :: halo
748 integer,
optional,
intent(in) :: clock
753 integer :: stagger_local
756 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
758 stagger_local = cgrid_ne
759 if (
present(stagger)) stagger_local = stagger
762 if (
present(direction))
then ;
if (direction > 0) dirflag = direction ;
endif
764 if (
present(halo) .and. mom_dom%thin_halo_updates)
then
766 mom_dom%mpp_domain, flags=dirflag, gridtype=stagger_local, &
767 whalo=halo, ehalo=halo, shalo=halo, nhalo=halo)
770 mom_dom%mpp_domain, flags=dirflag, gridtype=stagger_local)
773 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
781 integer,
intent(in) :: id_update
784 real,
dimension(:,:),
intent(inout) :: u_cmpt
787 real,
dimension(:,:),
intent(inout) :: v_cmpt
793 integer,
optional,
intent(in) :: direction
799 integer,
optional,
intent(in) :: stagger
802 integer,
optional,
intent(in) :: halo
804 integer,
optional,
intent(in) :: clock
807 integer :: stagger_local
810 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
812 stagger_local = cgrid_ne
813 if (
present(stagger)) stagger_local = stagger
816 if (
present(direction))
then ;
if (direction > 0) dirflag = direction ;
endif
818 if (
present(halo) .and. mom_dom%thin_halo_updates)
then
819 call mpp_complete_update_domains(id_update, u_cmpt, v_cmpt, &
820 mom_dom%mpp_domain, flags=dirflag, gridtype=stagger_local, &
821 whalo=halo, ehalo=halo, shalo=halo, nhalo=halo)
823 call mpp_complete_update_domains(id_update, u_cmpt, v_cmpt, &
824 mom_dom%mpp_domain, flags=dirflag, gridtype=stagger_local)
827 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
835 integer,
intent(in) :: id_update
838 real,
dimension(:,:,:),
intent(inout) :: u_cmpt
841 real,
dimension(:,:,:),
intent(inout) :: v_cmpt
847 integer,
optional,
intent(in) :: direction
853 integer,
optional,
intent(in) :: stagger
856 integer,
optional,
intent(in) :: halo
858 integer,
optional,
intent(in) :: clock
861 integer :: stagger_local
864 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
866 stagger_local = cgrid_ne
867 if (
present(stagger)) stagger_local = stagger
870 if (
present(direction))
then ;
if (direction > 0) dirflag = direction ;
endif
872 if (
present(halo) .and. mom_dom%thin_halo_updates)
then
873 call mpp_complete_update_domains(id_update, u_cmpt, v_cmpt, &
874 mom_dom%mpp_domain, flags=dirflag, gridtype=stagger_local, &
875 whalo=halo, ehalo=halo, shalo=halo, nhalo=halo)
877 call mpp_complete_update_domains(id_update, u_cmpt, v_cmpt, &
878 mom_dom%mpp_domain, flags=dirflag, gridtype=stagger_local)
881 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
888 type(group_pass_type),
intent(inout) :: group
891 real,
dimension(:,:),
intent(inout) :: array
896 integer,
optional,
intent(in) :: sideflag
900 integer,
optional,
intent(in) :: position
903 integer,
optional,
intent(in) :: halo
905 integer,
optional,
intent(in) :: clock
910 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
913 if (
present(sideflag))
then ;
if (sideflag > 0) dirflag = sideflag ;
endif
915 if (mpp_group_update_initialized(group))
then
916 call mpp_reset_group_update_field(group,array)
917 elseif (
present(halo) .and. mom_dom%thin_halo_updates)
then
918 call mpp_create_group_update(group, array, mom_dom%mpp_domain, flags=dirflag, &
919 position=position, whalo=halo, ehalo=halo, &
920 shalo=halo, nhalo=halo)
922 call mpp_create_group_update(group, array, mom_dom%mpp_domain, flags=dirflag, &
926 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
933 type(group_pass_type),
intent(inout) :: group
936 real,
dimension(:,:,:),
intent(inout) :: array
941 integer,
optional,
intent(in) :: sideflag
945 integer,
optional,
intent(in) :: position
948 integer,
optional,
intent(in) :: halo
950 integer,
optional,
intent(in) :: clock
955 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
958 if (
present(sideflag))
then ;
if (sideflag > 0) dirflag = sideflag ;
endif
960 if (mpp_group_update_initialized(group))
then
961 call mpp_reset_group_update_field(group,array)
962 elseif (
present(halo) .and. mom_dom%thin_halo_updates)
then
963 call mpp_create_group_update(group, array, mom_dom%mpp_domain, flags=dirflag, &
964 position=position, whalo=halo, ehalo=halo, &
965 shalo=halo, nhalo=halo)
967 call mpp_create_group_update(group, array, mom_dom%mpp_domain, flags=dirflag, &
971 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
978 type(group_pass_type),
intent(inout) :: group
981 real,
dimension(:,:),
intent(inout) :: u_cmpt
984 real,
dimension(:,:),
intent(inout) :: v_cmpt
991 integer,
optional,
intent(in) :: direction
997 integer,
optional,
intent(in) :: stagger
1000 integer,
optional,
intent(in) :: halo
1002 integer,
optional,
intent(in) :: clock
1005 integer :: stagger_local
1008 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
1010 stagger_local = cgrid_ne
1011 if (
present(stagger)) stagger_local = stagger
1014 if (
present(direction))
then ;
if (direction > 0) dirflag = direction ;
endif
1016 if (mpp_group_update_initialized(group))
then
1017 call mpp_reset_group_update_field(group,u_cmpt, v_cmpt)
1018 elseif (
present(halo) .and. mom_dom%thin_halo_updates)
then
1019 call mpp_create_group_update(group, u_cmpt, v_cmpt, mom_dom%mpp_domain, &
1020 flags=dirflag, gridtype=stagger_local, whalo=halo, ehalo=halo, &
1021 shalo=halo, nhalo=halo)
1023 call mpp_create_group_update(group, u_cmpt, v_cmpt, mom_dom%mpp_domain, &
1024 flags=dirflag, gridtype=stagger_local)
1027 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
1034 type(group_pass_type),
intent(inout) :: group
1037 real,
dimension(:,:,:),
intent(inout) :: u_cmpt
1040 real,
dimension(:,:,:),
intent(inout) :: v_cmpt
1047 integer,
optional,
intent(in) :: direction
1053 integer,
optional,
intent(in) :: stagger
1056 integer,
optional,
intent(in) :: halo
1058 integer,
optional,
intent(in) :: clock
1062 integer :: stagger_local
1065 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
1067 stagger_local = cgrid_ne
1068 if (
present(stagger)) stagger_local = stagger
1071 if (
present(direction))
then ;
if (direction > 0) dirflag = direction ;
endif
1073 if (mpp_group_update_initialized(group))
then
1074 call mpp_reset_group_update_field(group,u_cmpt, v_cmpt)
1075 elseif (
present(halo) .and. mom_dom%thin_halo_updates)
then
1076 call mpp_create_group_update(group, u_cmpt, v_cmpt, mom_dom%mpp_domain, &
1077 flags=dirflag, gridtype=stagger_local, whalo=halo, ehalo=halo, &
1078 shalo=halo, nhalo=halo)
1080 call mpp_create_group_update(group, u_cmpt, v_cmpt, mom_dom%mpp_domain, &
1081 flags=dirflag, gridtype=stagger_local)
1084 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
1090 type(group_pass_type),
intent(inout) :: group
1096 integer,
optional,
intent(in) :: clock
1100 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
1102 call mpp_do_group_update(group, mom_dom%mpp_domain, d_type)
1104 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
1110 type(group_pass_type),
intent(inout) :: group
1116 integer,
optional,
intent(in) :: clock
1121 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
1123 call mpp_start_group_update(group, mom_dom%mpp_domain, d_type)
1125 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
1131 type(group_pass_type),
intent(inout) :: group
1137 integer,
optional,
intent(in) :: clock
1141 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_begin(clock) ;
endif
1143 call mpp_complete_group_update(group, mom_dom%mpp_domain, d_type)
1145 if (
present(clock))
then ;
if (clock>0)
call cpu_clock_end(clock) ;
endif
1152 subroutine mom_domains_init(MOM_dom, param_file, symmetric, static_memory, &
1153 NIHALO, NJHALO, NIGLOBAL, NJGLOBAL, NIPROC, NJPROC, &
1154 min_halo, domain_name, include_name, param_suffix)
1159 logical,
optional,
intent(in) :: symmetric
1162 logical,
optional,
intent(in) :: static_memory
1165 integer,
optional,
intent(in) :: nihalo
1167 integer,
optional,
intent(in) :: njhalo
1169 integer,
optional,
intent(in) :: niglobal
1171 integer,
optional,
intent(in) :: njglobal
1173 integer,
optional,
intent(in) :: niproc
1175 integer,
optional,
intent(in) :: njproc
1177 integer,
dimension(2),
optional,
intent(inout) :: min_halo
1180 character(len=*),
optional,
intent(in) :: domain_name
1182 character(len=*),
optional,
intent(in) :: include_name
1184 character(len=*),
optional,
intent(in) :: param_suffix
1188 integer,
dimension(2) :: layout = (/ 1, 1 /)
1189 integer,
dimension(2) :: io_layout = (/ 0, 0 /)
1190 integer,
dimension(4) :: global_indices
1195 integer :: nihalo_dflt, njhalo_dflt
1196 integer :: pe, proc_used
1197 integer :: x_flags, y_flags
1198 logical :: reentrant_x, reentrant_y, tripolar_n, is_static
1199 logical :: mask_table_exists
1200 character(len=128) :: mask_table, inputdir
1201 character(len=64) :: dom_name, inc_nm
1202 character(len=200) :: mesg
1204 integer :: xsiz, ysiz, nip_parsed, njp_parsed
1205 integer :: isc,iec,jsc,jec
1206 character(len=8) :: char_xsiz, char_ysiz, char_niglobal, char_njglobal
1207 character(len=40) :: nihalo_nm, njhalo_nm, layout_nm, io_layout_nm, masktable_nm
1208 character(len=40) :: niproc_nm, njproc_nm
1209 integer :: xhalo_d2,yhalo_d2
1211 #include "version_variable.h"
1212 character(len=40) :: mdl
1214 if (.not.
associated(mom_dom))
then
1216 allocate(mom_dom%mpp_domain)
1217 allocate(mom_dom%mpp_domain_d2)
1221 proc_used = num_pes()
1225 mom_dom%symmetric = .true.
1226 if (
present(symmetric))
then ; mom_dom%symmetric = symmetric ;
endif
1227 if (
present(min_halo)) mdl = trim(mdl)//
" min_halo"
1229 dom_name =
"MOM" ; inc_nm =
"MOM_memory.h"
1230 if (
present(domain_name)) dom_name = trim(domain_name)
1231 if (
present(include_name)) inc_nm = trim(include_name)
1233 nihalo_nm =
"NIHALO" ; njhalo_nm =
"NJHALO"
1234 layout_nm =
"LAYOUT" ; io_layout_nm =
"IO_LAYOUT" ; masktable_nm =
"MASKTABLE"
1235 niproc_nm =
"NIPROC" ; njproc_nm =
"NJPROC"
1236 if (
present(param_suffix))
then ;
if (len(trim(adjustl(param_suffix))) > 0)
then
1237 nihalo_nm =
"NIHALO"//(trim(adjustl(param_suffix)))
1238 njhalo_nm =
"NJHALO"//(trim(adjustl(param_suffix)))
1239 layout_nm =
"LAYOUT"//(trim(adjustl(param_suffix)))
1240 io_layout_nm =
"IO_LAYOUT"//(trim(adjustl(param_suffix)))
1241 masktable_nm =
"MASKTABLE"//(trim(adjustl(param_suffix)))
1242 niproc_nm =
"NIPROC"//(trim(adjustl(param_suffix)))
1243 njproc_nm =
"NJPROC"//(trim(adjustl(param_suffix)))
1246 is_static = .false. ;
if (
present(static_memory)) is_static = static_memory
1248 if (.not.
present(nihalo))
call mom_error(fatal,
"NIHALO must be "// &
1249 "present in the call to MOM_domains_init with static memory.")
1250 if (.not.
present(njhalo))
call mom_error(fatal,
"NJHALO must be "// &
1251 "present in the call to MOM_domains_init with static memory.")
1252 if (.not.
present(niglobal))
call mom_error(fatal,
"NIGLOBAL must be "// &
1253 "present in the call to MOM_domains_init with static memory.")
1254 if (.not.
present(njglobal))
call mom_error(fatal,
"NJGLOBAL must be "// &
1255 "present in the call to MOM_domains_init with static memory.")
1256 if (.not.
present(niproc))
call mom_error(fatal,
"NIPROC must be "// &
1257 "present in the call to MOM_domains_init with static memory.")
1258 if (.not.
present(njproc))
call mom_error(fatal,
"NJPROC must be "// &
1259 "present in the call to MOM_domains_init with static memory.")
1264 call get_param(param_file, mdl,
"REENTRANT_X", reentrant_x, &
1265 "If true, the domain is zonally reentrant.", default=.true.)
1266 call get_param(param_file, mdl,
"REENTRANT_Y", reentrant_y, &
1267 "If true, the domain is meridionally reentrant.", &
1269 call get_param(param_file, mdl,
"TRIPOLAR_N", tripolar_n, &
1270 "Use tripolar connectivity at the northern edge of the "//&
1271 "domain. With TRIPOLAR_N, NIGLOBAL must be even.", &
1274 #ifndef NOT_SET_AFFINITY
1309 call log_param(param_file, mdl,
"!SYMMETRIC_MEMORY_", mom_dom%symmetric, &
1310 "If defined, the velocity point data domain includes "//&
1311 "every face of the thickness points. In other words, "//&
1312 "some arrays are larger than others, depending on where "//&
1313 "they are on the staggered grid. Also, the starting "//&
1314 "index of the velocity-point arrays is usually 0, not 1. "//&
1315 "This can only be set at compile time.",&
1317 call get_param(param_file, mdl,
"NONBLOCKING_UPDATES", mom_dom%nonblocking_updates, &
1318 "If true, non-blocking halo updates may be used.", &
1319 default=.false., layoutparam=.true.)
1320 call get_param(param_file, mdl,
"THIN_HALO_UPDATES", mom_dom%thin_halo_updates, &
1321 "If true, optional arguments may be used to specify the "//&
1322 "the width of the halos that are updated with each call.", &
1323 default=.true., layoutparam=.true.)
1325 nihalo_dflt = 4 ; njhalo_dflt = 4
1326 if (
present(nihalo)) nihalo_dflt = nihalo
1327 if (
present(njhalo)) njhalo_dflt = njhalo
1329 call log_param(param_file, mdl,
"!STATIC_MEMORY_", is_static, &
1330 "If STATIC_MEMORY_ is defined, the principle variables "//&
1331 "will have sizes that are statically determined at "//&
1332 "compile time. Otherwise the sizes are not determined "//&
1333 "until run time. The STATIC option is substantially "//&
1334 "faster, but does not allow the PE count to be changed "//&
1335 "at run time. This can only be set at compile time.",&
1338 call get_param(param_file, mdl, trim(nihalo_nm), mom_dom%nihalo, &
1339 "The number of halo points on each side in the "//&
1340 "x-direction. With STATIC_MEMORY_ this is set as NIHALO_ "//&
1341 "in "//trim(inc_nm)//
" at compile time; without STATIC_MEMORY_ "//&
1342 "the default is NIHALO_ in "//trim(inc_nm)//
" (if defined) or 2.", &
1343 default=4, static_value=nihalo_dflt, layoutparam=.true.)
1344 call get_param(param_file, mdl, trim(njhalo_nm), mom_dom%njhalo, &
1345 "The number of halo points on each side in the "//&
1346 "y-direction. With STATIC_MEMORY_ this is set as NJHALO_ "//&
1347 "in "//trim(inc_nm)//
" at compile time; without STATIC_MEMORY_ "//&
1348 "the default is NJHALO_ in "//trim(inc_nm)//
" (if defined) or 2.", &
1349 default=4, static_value=njhalo_dflt, layoutparam=.true.)
1350 if (
present(min_halo))
then
1351 mom_dom%nihalo = max(mom_dom%nihalo, min_halo(1))
1352 min_halo(1) = mom_dom%nihalo
1353 mom_dom%njhalo = max(mom_dom%njhalo, min_halo(2))
1354 min_halo(2) = mom_dom%njhalo
1355 call log_param(param_file, mdl,
"!NIHALO min_halo", mom_dom%nihalo, layoutparam=.true.)
1356 call log_param(param_file, mdl,
"!NJHALO min_halo", mom_dom%nihalo, layoutparam=.true.)
1359 call get_param(param_file, mdl,
"NIGLOBAL", mom_dom%niglobal, &
1360 "The total number of thickness grid points in the "//&
1361 "x-direction in the physical domain. With STATIC_MEMORY_ "//&
1362 "this is set in "//trim(inc_nm)//
" at compile time.", &
1363 static_value=niglobal)
1364 call get_param(param_file, mdl,
"NJGLOBAL", mom_dom%njglobal, &
1365 "The total number of thickness grid points in the "//&
1366 "y-direction in the physical domain. With STATIC_MEMORY_ "//&
1367 "this is set in "//trim(inc_nm)//
" at compile time.", &
1368 static_value=njglobal)
1369 if (mom_dom%niglobal /= niglobal)
call mom_error(fatal,
"MOM_domains_init: " // &
1370 "static mismatch for NIGLOBAL_ domain size. Header file does not match input namelist")
1371 if (mom_dom%njglobal /= njglobal)
call mom_error(fatal,
"MOM_domains_init: " // &
1372 "static mismatch for NJGLOBAL_ domain size. Header file does not match input namelist")
1374 if (.not.
present(min_halo))
then
1375 if (mom_dom%nihalo /= nihalo)
call mom_error(fatal,
"MOM_domains_init: " // &
1376 "static mismatch for "//trim(nihalo_nm)//
" domain size")
1377 if (mom_dom%njhalo /= njhalo)
call mom_error(fatal,
"MOM_domains_init: " // &
1378 "static mismatch for "//trim(njhalo_nm)//
" domain size")
1381 call get_param(param_file, mdl,
"NIGLOBAL", mom_dom%niglobal, &
1382 "The total number of thickness grid points in the "//&
1383 "x-direction in the physical domain. With STATIC_MEMORY_ "//&
1384 "this is set in "//trim(inc_nm)//
" at compile time.", &
1385 fail_if_missing=.true.)
1386 call get_param(param_file, mdl,
"NJGLOBAL", mom_dom%njglobal, &
1387 "The total number of thickness grid points in the "//&
1388 "y-direction in the physical domain. With STATIC_MEMORY_ "//&
1389 "this is set in "//trim(inc_nm)//
" at compile time.", &
1390 fail_if_missing=.true.)
1393 global_indices(1) = 1 ; global_indices(2) = mom_dom%niglobal
1394 global_indices(3) = 1 ; global_indices(4) = mom_dom%njglobal
1396 call get_param(param_file, mdl,
"INPUTDIR", inputdir, do_not_log=.true., default=
".")
1399 call get_param(param_file, mdl, trim(masktable_nm), mask_table, &
1400 "A text file to specify n_mask, layout and mask_list. "//&
1401 "This feature masks out processors that contain only land points. "//&
1402 "The first line of mask_table is the number of regions to be masked out. "//&
1403 "The second line is the layout of the model and must be "//&
1404 "consistent with the actual model layout. "//&
1405 "The following (n_mask) lines give the logical positions "//&
1406 "of the processors that are masked out. The mask_table "//&
1407 "can be created by tools like check_mask. The "//&
1408 "following example of mask_table masks out 2 processors, "//&
1409 "(1,2) and (3,6), out of the 24 in a 4x6 layout: \n"//&
1410 " 2\n 4,6\n 1,2\n 3,6\n", default=
"MOM_mask_table", &
1412 mask_table = trim(inputdir)//trim(mask_table)
1413 mask_table_exists = file_exist(mask_table)
1416 layout(1) = niproc ; layout(2) = njproc
1418 call get_param(param_file, mdl, trim(layout_nm), layout, &
1419 "The processor layout to be used, or 0, 0 to automatically "//&
1420 "set the layout based on the number of processors.", default=0, &
1422 call get_param(param_file, mdl, trim(niproc_nm), nip_parsed, &
1423 "The number of processors in the x-direction.", default=-1, &
1425 call get_param(param_file, mdl, trim(njproc_nm), njp_parsed, &
1426 "The number of processors in the y-direction.", default=-1, &
1428 if (nip_parsed > -1)
then
1429 if ((layout(1) > 0) .and. (layout(1) /= nip_parsed)) &
1430 call mom_error(fatal, trim(layout_nm)//
" and "//trim(niproc_nm)//
" set inconsistently. "//&
1431 "Only LAYOUT should be used.")
1432 layout(1) = nip_parsed
1433 call mom_mesg(trim(niproc_nm)//
" used to set "//trim(layout_nm)//
" in dynamic mode. "//&
1434 "Shift to using "//trim(layout_nm)//
" instead.")
1436 if (njp_parsed > -1)
then
1437 if ((layout(2) > 0) .and. (layout(2) /= njp_parsed)) &
1438 call mom_error(fatal, trim(layout_nm)//
" and "//trim(njproc_nm)//
" set inconsistently. "//&
1439 "Only "//trim(layout_nm)//
" should be used.")
1440 layout(2) = njp_parsed
1441 call mom_mesg(trim(njproc_nm)//
" used to set "//trim(layout_nm)//
" in dynamic mode. "//&
1442 "Shift to using "//trim(layout_nm)//
" instead.")
1445 if ( layout(1)==0 .and. layout(2)==0 ) &
1446 call mpp_define_layout(global_indices, proc_used, layout)
1447 if ( layout(1)/=0 .and. layout(2)==0 ) layout(2) = proc_used/layout(1)
1448 if ( layout(1)==0 .and. layout(2)/=0 ) layout(1) = proc_used/layout(2)
1450 if (layout(1)*layout(2) /= proc_used .and. (.not. mask_table_exists) )
then
1451 write(mesg,
'("MOM_domains_init: The product of the two components of layout, ", &
1452 & 2i4,", is not the number of PEs used, ",i5,".")') &
1453 layout(1),layout(2),proc_used
1457 call log_param(param_file, mdl, trim(niproc_nm), layout(1), &
1458 "The number of processors in the x-direction. With "//&
1459 "STATIC_MEMORY_ this is set in "//trim(inc_nm)//
" at compile time.",&
1461 call log_param(param_file, mdl, trim(njproc_nm), layout(2), &
1462 "The number of processors in the y-direction. With "//&
1463 "STATIC_MEMORY_ this is set in "//trim(inc_nm)//
" at compile time.",&
1465 call log_param(param_file, mdl, trim(layout_nm), layout, &
1466 "The processor layout that was actually used.",&
1470 if (layout(1)*layout(2)>mom_dom%niglobal*mom_dom%njglobal)
then
1471 write(mesg,
'(a,2(i5,x,a))')
'You requested to use',layout(1)*layout(2), &
1472 'PEs but there are only',mom_dom%niglobal*mom_dom%njglobal,
'columns in the model'
1476 if (mask_table_exists)
then
1477 call mom_error(note,
'MOM_domains_init: reading maskmap information from '//&
1479 allocate(mom_dom%maskmap(layout(1), layout(2)))
1480 call parse_mask_table(mask_table, mom_dom%maskmap, dom_name)
1485 io_layout(:) = (/ 1, 1 /)
1486 call get_param(param_file, mdl, trim(io_layout_nm), io_layout, &
1487 "The processor layout to be used, or 0,0 to automatically "//&
1488 "set the io_layout to be the same as the layout.", default=1, &
1491 if (io_layout(1) < 0)
then
1492 write(mesg,
'("MOM_domains_init: IO_LAYOUT(1) = ",i4,". Negative values "//&
1493 &"are not allowed in ")') io_layout(1)
1494 call mom_error(fatal, mesg//trim(io_layout_nm))
1495 elseif (io_layout(1) > 0)
then ;
if (modulo(layout(1), io_layout(1)) /= 0)
then
1496 write(mesg,
'("MOM_domains_init: The i-direction I/O-layout, IO_LAYOUT(1)=",i4, &
1497 &", does not evenly divide the i-direction layout, NIPROC=,",i4,".")') &
1498 io_layout(1),layout(1)
1502 if (io_layout(2) < 0)
then
1503 write(mesg,
'("MOM_domains_init: IO_LAYOUT(2) = ",i4,". Negative values "//&
1504 &"are not allowed in ")') io_layout(2)
1505 call mom_error(fatal, mesg//trim(io_layout_nm))
1506 elseif (io_layout(2) /= 0)
then ;
if (modulo(layout(2), io_layout(2)) /= 0)
then
1507 write(mesg,
'("MOM_domains_init: The j-direction I/O-layout, IO_LAYOUT(2)=",i4, &
1508 &", does not evenly divide the j-direction layout, NJPROC=,",i4,".")') &
1509 io_layout(2),layout(2)
1513 if (io_layout(2) == 0) io_layout(2) = layout(2)
1514 if (io_layout(1) == 0) io_layout(1) = layout(1)
1516 x_flags = 0 ; y_flags = 0
1517 if (reentrant_x) x_flags = cyclic_global_domain
1518 if (reentrant_y) y_flags = cyclic_global_domain
1519 if (tripolar_n)
then
1520 y_flags = fold_north_edge
1521 if (reentrant_y)
call mom_error(fatal,
"MOM_domains: "// &
1522 "TRIPOLAR_N and REENTRANT_Y may not be defined together.")
1525 global_indices(1) = 1 ; global_indices(2) = mom_dom%niglobal
1526 global_indices(3) = 1 ; global_indices(4) = mom_dom%njglobal
1528 if (mask_table_exists)
then
1529 call mom_define_domain( global_indices, layout, mom_dom%mpp_domain, &
1530 xflags=x_flags, yflags=y_flags, &
1531 xhalo=mom_dom%nihalo, yhalo=mom_dom%njhalo, &
1532 symmetry = mom_dom%symmetric, name=dom_name, &
1533 maskmap=mom_dom%maskmap )
1535 call mom_define_domain( global_indices, layout, mom_dom%mpp_domain, &
1536 xflags=x_flags, yflags=y_flags, &
1537 xhalo=mom_dom%nihalo, yhalo=mom_dom%njhalo, &
1538 symmetry = mom_dom%symmetric, name=dom_name)
1541 if ((io_layout(1) > 0) .and. (io_layout(2) > 0) .and. &
1542 (layout(1)*layout(2) > 1))
then
1543 call mom_define_io_domain(mom_dom%mpp_domain, io_layout)
1547 mom_dom%X_FLAGS = x_flags
1548 mom_dom%Y_FLAGS = y_flags
1549 mom_dom%layout = layout
1550 mom_dom%io_layout = io_layout
1555 call mpp_get_compute_domain(mom_dom%mpp_domain,isc,iec,jsc,jec)
1556 xsiz = iec - isc + 1
1557 ysiz = jec - jsc + 1
1558 if (xsiz*niproc /= mom_dom%niglobal .OR. ysiz*njproc /= mom_dom%njglobal)
then
1559 write( char_xsiz,
'(i4)' ) niproc
1560 write( char_ysiz,
'(i4)' ) njproc
1561 write( char_niglobal,
'(i4)' ) mom_dom%niglobal
1562 write( char_njglobal,
'(i4)' ) mom_dom%njglobal
1563 call mom_error(warning,
'MOM_domains: Processor decomposition (NIPROC_,NJPROC_) = (' &
1564 //trim(char_xsiz)//
','//trim(char_ysiz)// &
1565 ') does not evenly divide size set by preprocessor macro ('&
1566 //trim(char_niglobal)//
','//trim(char_njglobal)//
'). ')
1567 call mom_error(fatal,
'MOM_domains: #undef STATIC_MEMORY_ in "//trim(inc_nm)//" to use &
1568 &dynamic allocation, or change processor decomposition to evenly divide the domain.')
1572 global_indices(1) = 1 ; global_indices(2) = int(mom_dom%niglobal/2)
1573 global_indices(3) = 1 ; global_indices(4) = int(mom_dom%njglobal/2)
1577 xhalo_d2 = int(mom_dom%nihalo/2)
1578 yhalo_d2 = int(mom_dom%njhalo/2)
1579 if (mask_table_exists)
then
1580 call mom_define_domain( global_indices, layout, mom_dom%mpp_domain_d2, &
1581 xflags=x_flags, yflags=y_flags, &
1582 xhalo=xhalo_d2, yhalo=yhalo_d2, &
1583 symmetry = mom_dom%symmetric, name=trim(
"MOMc"), &
1584 maskmap=mom_dom%maskmap )
1586 call mom_define_domain( global_indices, layout, mom_dom%mpp_domain_d2, &
1587 xflags=x_flags, yflags=y_flags, &
1588 xhalo=xhalo_d2, yhalo=yhalo_d2, &
1589 symmetry = mom_dom%symmetric, name=trim(
"MOMc"))
1592 if ((io_layout(1) > 0) .and. (io_layout(2) > 0) .and. &
1593 (layout(1)*layout(2) > 1))
then
1594 call mom_define_io_domain(mom_dom%mpp_domain_d2, io_layout)
1601 subroutine clone_md_to_md(MD_in, MOM_dom, min_halo, halo_size, symmetric, &
1607 integer,
dimension(2), &
1608 optional,
intent(inout) :: min_halo
1611 integer,
optional,
intent(in) :: halo_size
1614 logical,
optional,
intent(in) :: symmetric
1618 optional,
intent(in) :: domain_name
1621 integer :: global_indices(4)
1622 logical :: mask_table_exists
1623 character(len=64) :: dom_name
1625 if (.not.
associated(mom_dom))
then
1627 allocate(mom_dom%mpp_domain)
1628 allocate(mom_dom%mpp_domain_d2)
1632 mom_dom%niglobal = md_in%niglobal ; mom_dom%njglobal = md_in%njglobal
1633 mom_dom%nihalo = md_in%nihalo ; mom_dom%njhalo = md_in%njhalo
1635 mom_dom%symmetric = md_in%symmetric
1636 mom_dom%nonblocking_updates = md_in%nonblocking_updates
1638 mom_dom%X_FLAGS = md_in%X_FLAGS ; mom_dom%Y_FLAGS = md_in%Y_FLAGS
1639 mom_dom%layout(:) = md_in%layout(:) ; mom_dom%io_layout(:) = md_in%io_layout(:)
1641 if (
associated(md_in%maskmap))
then
1642 mask_table_exists = .true.
1643 allocate(mom_dom%maskmap(mom_dom%layout(1), mom_dom%layout(2)))
1644 mom_dom%maskmap(:,:) = md_in%maskmap(:,:)
1646 mask_table_exists = .false.
1649 if (
present(halo_size) .and.
present(min_halo))
call mom_error(fatal, &
1650 "clone_MOM_domain can not have both halo_size and min_halo present.")
1652 if (
present(min_halo))
then
1653 mom_dom%nihalo = max(mom_dom%nihalo, min_halo(1))
1654 min_halo(1) = mom_dom%nihalo
1655 mom_dom%njhalo = max(mom_dom%njhalo, min_halo(2))
1656 min_halo(2) = mom_dom%njhalo
1659 if (
present(halo_size))
then
1660 mom_dom%nihalo = halo_size ; mom_dom%njhalo = halo_size
1663 if (
present(symmetric))
then ; mom_dom%symmetric = symmetric ;
endif
1666 if (
present(domain_name)) dom_name = trim(domain_name)
1668 global_indices(1) = 1 ; global_indices(2) = mom_dom%niglobal
1669 global_indices(3) = 1 ; global_indices(4) = mom_dom%njglobal
1670 if (mask_table_exists)
then
1671 call mom_define_domain( global_indices, mom_dom%layout, mom_dom%mpp_domain, &
1672 xflags=mom_dom%X_FLAGS, yflags=mom_dom%Y_FLAGS, &
1673 xhalo=mom_dom%nihalo, yhalo=mom_dom%njhalo, &
1674 symmetry = mom_dom%symmetric, name=dom_name, &
1675 maskmap=mom_dom%maskmap )
1677 call mom_define_domain( global_indices, mom_dom%layout, mom_dom%mpp_domain, &
1678 xflags=mom_dom%X_FLAGS, yflags=mom_dom%Y_FLAGS, &
1679 xhalo=mom_dom%nihalo, yhalo=mom_dom%njhalo, &
1680 symmetry = mom_dom%symmetric, name=dom_name)
1683 if ((mom_dom%io_layout(1) + mom_dom%io_layout(2) > 0) .and. &
1684 (mom_dom%layout(1)*mom_dom%layout(2) > 1))
then
1685 call mom_define_io_domain(mom_dom%mpp_domain, mom_dom%io_layout)
1693 subroutine clone_md_to_d2d(MD_in, mpp_domain, min_halo, halo_size, symmetric, &
1696 type(domain2d),
intent(inout) :: mpp_domain
1697 integer,
dimension(2), &
1698 optional,
intent(inout) :: min_halo
1701 integer,
optional,
intent(in) :: halo_size
1704 logical,
optional,
intent(in) :: symmetric
1708 optional,
intent(in) :: domain_name
1711 integer :: global_indices(4), layout(2), io_layout(2)
1712 integer :: X_FLAGS, Y_FLAGS, niglobal, njglobal, nihalo, njhalo
1713 logical :: symmetric_dom
1714 character(len=64) :: dom_name
1717 niglobal = md_in%niglobal ; njglobal = md_in%njglobal
1718 nihalo = md_in%nihalo ; njhalo = md_in%njhalo
1720 symmetric_dom = md_in%symmetric
1722 x_flags = md_in%X_FLAGS ; y_flags = md_in%Y_FLAGS
1723 layout(:) = md_in%layout(:) ; io_layout(:) = md_in%io_layout(:)
1725 if (
present(halo_size) .and.
present(min_halo))
call mom_error(fatal, &
1726 "clone_MOM_domain can not have both halo_size and min_halo present.")
1728 if (
present(min_halo))
then
1729 nihalo = max(nihalo, min_halo(1))
1730 njhalo = max(njhalo, min_halo(2))
1731 min_halo(1) = nihalo ; min_halo(2) = njhalo
1734 if (
present(halo_size))
then
1735 nihalo = halo_size ; njhalo = halo_size
1738 if (
present(symmetric))
then ; symmetric_dom = symmetric ;
endif
1741 if (
present(domain_name)) dom_name = trim(domain_name)
1743 global_indices(1) = 1 ; global_indices(2) = niglobal
1744 global_indices(3) = 1 ; global_indices(4) = njglobal
1745 if (
associated(md_in%maskmap))
then
1746 call mom_define_domain( global_indices, layout, mpp_domain, &
1747 xflags=x_flags, yflags=y_flags, &
1748 xhalo=nihalo, yhalo=njhalo, &
1749 symmetry = symmetric, name=dom_name, &
1750 maskmap=md_in%maskmap )
1752 call mom_define_domain( global_indices, layout, mpp_domain, &
1753 xflags=x_flags, yflags=y_flags, &
1754 xhalo=nihalo, yhalo=njhalo, &
1755 symmetry = symmetric, name=dom_name)
1758 if ((io_layout(1) + io_layout(2) > 0) .and. &
1759 (layout(1)*layout(2) > 1))
then
1760 call mom_define_io_domain(mpp_domain, io_layout)
1767 isg, ieg, jsg, jeg, idg_offset, jdg_offset, &
1768 symmetric, local_indexing, index_offset)
1770 intent(in) :: domain
1771 integer,
intent(out) :: isc
1772 integer,
intent(out) :: iec
1773 integer,
intent(out) :: jsc
1774 integer,
intent(out) :: jec
1775 integer,
intent(out) :: isd
1776 integer,
intent(out) :: ied
1777 integer,
intent(out) :: jsd
1778 integer,
intent(out) :: jed
1779 integer,
intent(out) :: isg
1780 integer,
intent(out) :: ieg
1781 integer,
intent(out) :: jsg
1782 integer,
intent(out) :: jeg
1783 integer,
intent(out) :: idg_offset
1785 integer,
intent(out) :: jdg_offset
1787 logical,
intent(out) :: symmetric
1788 logical,
optional,
intent(in) :: local_indexing
1790 integer,
optional,
intent(in) :: index_offset
1797 local = .true. ;
if (
present(local_indexing)) local = local_indexing
1798 ind_off = 0 ;
if (
present(index_offset)) ind_off = index_offset
1800 call mpp_get_compute_domain(domain%mpp_domain, isc, iec, jsc, jec)
1801 call mpp_get_data_domain(domain%mpp_domain, isd, ied, jsd, jed)
1802 call mpp_get_global_domain(domain%mpp_domain, isg, ieg, jsg, jeg)
1806 idg_offset = isd-1 ; jdg_offset = jsd-1
1807 isc = isc-isd+1 ; iec = iec-isd+1 ; jsc = jsc-jsd+1 ; jec = jec-jsd+1
1808 ied = ied-isd+1 ; jed = jed-jsd+1
1811 idg_offset = 0 ; jdg_offset = 0
1813 if (ind_off /= 0)
then
1814 idg_offset = idg_offset + ind_off ; jdg_offset = jdg_offset + ind_off
1815 isc = isc + ind_off ; iec = iec + ind_off
1816 jsc = jsc + ind_off ; jec = jec + ind_off
1817 isd = isd + ind_off ; ied = ied + ind_off
1818 jsd = jsd + ind_off ; jed = jed + ind_off
1820 symmetric = domain%symmetric
1825 isd_d2, ied_d2, jsd_d2, jed_d2,&
1826 isg_d2, ieg_d2, jsg_d2, jeg_d2)
1828 intent(in) :: domain
1829 integer,
intent(out) :: isc_d2
1830 integer,
intent(out) :: iec_d2
1831 integer,
intent(out) :: jsc_d2
1832 integer,
intent(out) :: jec_d2
1833 integer,
intent(out) :: isd_d2
1834 integer,
intent(out) :: ied_d2
1835 integer,
intent(out) :: jsd_d2
1836 integer,
intent(out) :: jed_d2
1837 integer,
intent(out) :: isg_d2
1838 integer,
intent(out) :: ieg_d2
1839 integer,
intent(out) :: jsg_d2
1840 integer,
intent(out) :: jeg_d2
1842 call mpp_get_compute_domain(domain%mpp_domain_d2, isc_d2, iec_d2, jsc_d2, jec_d2)
1843 call mpp_get_data_domain(domain%mpp_domain_d2, isd_d2, ied_d2, jsd_d2, jed_d2)
1844 call mpp_get_global_domain (domain%mpp_domain_d2, isg_d2, ieg_d2, jsg_d2, jeg_d2)
1846 isc_d2 = isc_d2-isd_d2+1 ; iec_d2 = iec_d2-isd_d2+1
1847 jsc_d2 = jsc_d2-jsd_d2+1 ; jec_d2 = jec_d2-jsd_d2+1
1848 ied_d2 = ied_d2-isd_d2+1 ; jed_d2 = jed_d2-jsd_d2+1
1849 isd_d2 = 1 ; jsd_d2 = 1
1856 integer,
intent(in) :: size
1857 integer,
intent(out) :: is
1858 integer,
intent(out) :: ie
1859 logical,
optional,
intent(in) :: symmetric
1863 character(len=120) :: mesg, mesg2
1864 integer :: isc, iec, jsc, jec, isd, ied, jsd, jed
1866 call mpp_get_compute_domain(domain%mpp_domain, isc, iec, jsc, jec)
1867 call mpp_get_data_domain(domain%mpp_domain, isd, ied, jsd, jed)
1869 isc = isc-isd+1 ; iec = iec-isd+1 ; ied = ied-isd+1 ; isd = 1
1870 sym = domain%symmetric ;
if (
present(symmetric)) sym = symmetric
1872 if (
size == ied)
then ; is = isc ; ie = iec
1873 elseif (
size == 1+iec-isc)
then ; is = 1 ; ie =
size
1874 elseif (sym .and. (
size == 1+ied))
then ; is = isc ; ie = iec+1
1875 elseif (sym .and. (
size == 2+iec-isc))
then ; is = 1 ; ie = size+1
1877 write(mesg,
'("Unrecognized size ", i6, "in call to get_simple_array_i_ind. \")')
size
1879 write(mesg2,
'("Valid sizes are : ", 2i7)') ied, 1+iec-isc
1881 write(mesg2,
'("Valid sizes are : ", 4i7)') ied, 1+iec-isc, 1+ied, 2+iec-isc
1883 call mom_error(fatal, trim(mesg)//trim(mesg2))
1893 integer,
intent(in) :: size
1894 integer,
intent(out) :: js
1895 integer,
intent(out) :: je
1896 logical,
optional,
intent(in) :: symmetric
1900 character(len=120) :: mesg, mesg2
1901 integer :: isc, iec, jsc, jec, isd, ied, jsd, jed
1903 call mpp_get_compute_domain(domain%mpp_domain, isc, iec, jsc, jec)
1904 call mpp_get_data_domain(domain%mpp_domain, isd, ied, jsd, jed)
1906 jsc = jsc-jsd+1 ; jec = jec-jsd+1 ; jed = jed-jsd+1 ; jsd = 1
1907 sym = domain%symmetric ;
if (
present(symmetric)) sym = symmetric
1909 if (
size == jed)
then ; js = jsc ; je = jec
1910 elseif (
size == 1+jec-jsc)
then ; js = 1 ; je =
size
1911 elseif (sym .and. (
size == 1+jed))
then ; js = jsc ; je = jec+1
1912 elseif (sym .and. (
size == 2+jec-jsc))
then ; js = 1 ; je = size+1
1914 write(mesg,
'("Unrecognized size ", i6, "in call to get_simple_array_j_ind. \")')
size
1916 write(mesg2,
'("Valid sizes are : ", 2i7)') jed, 1+jec-jsc
1918 write(mesg2,
'("Valid sizes are : ", 4i7)') jed, 1+jec-jsc, 1+jed, 2+jec-jsc
1920 call mom_error(fatal, trim(mesg)//trim(mesg2))
1928 integer,
intent(out) :: niglobal
1929 integer,
intent(out) :: njglobal
1931 niglobal = domain%niglobal
1932 njglobal = domain%njglobal