4 !***********************************************************************
5 !* GNU Lesser General Public License
7 !* This file
is part of the GFDL Flexible Modeling System (FMS).
9 !* FMS
is free software: you can redistribute it and/or modify it under
10 !* the terms of the GNU Lesser General Public License as published by
11 !* the Free Software Foundation, either
version 3 of the License, or (at
12 !* your option) any later
version.
14 !* FMS
is distributed in the hope that it
will be useful, but WITHOUT
15 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 !* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 !* You should have
received a copy of the GNU Lesser General Public
20 !* License along with FMS. If
not, see <http:
21 !***********************************************************************
23 !#####################################################################
24 ! <SUBROUTINE NAME=
"mpp_get_info">
34 ! <IN NAME=
"unit" TYPE=
"integer"> </IN>
35 ! <OUT NAME=
"ndim" TYPE=
"integer"> </OUT>
36 ! <OUT NAME=
"nvar" TYPE=
"integer"> </OUT>
37 ! <OUT NAME=
"natt" TYPE=
"integer"> </OUT>
38 ! <OUT NAME=
"ntime" TYPE=
"integer"> </OUT>
49 call
mpp_error(FATAL,
'MPP_GET_INFO: invalid unit number, file ' 58 end subroutine mpp_get_info
60 !#####################################################################
61 ! <SUBROUTINE NAME=
"mpp_get_global_atts" INTERFACE=
"mpp_get_atts">
62 ! <IN NAME=
"unit" TYPE=
"integer"></IN>
63 ! <IN NAME=
"global_atts" TYPE=
"atttype" DIM=
"(:)"></IN>
65 subroutine mpp_get_global_atts(
unit, global_atts )
69 ! global_atts
is an attribute
type which
is allocated from the
73 type(atttype), intent(inout) :: global_atts(:)
78 call
mpp_error( FATAL,
'MPP_GET_INFO: invalid unit number,file ' 81 call
mpp_error(FATAL,
'MPP_GET_ATTS: atttype not dimensioned properly in calling routine, file ' 92 end subroutine mpp_get_global_atts
94 !#####################################################################
95 subroutine mpp_get_field_atts(
field,
name,
units, longname,
min,
max,
missing,
ndim, siz,
axes, atts, &
96 valid, scale,
add, checksum)
100 character(
len=*), intent(
out), optional :: longname
104 type(validtype), intent(
out), optional :: valid
105 real, intent(
out), optional :: scale
106 real, intent(
out), optional ::
add 116 if (PRESENT(longname)) longname =
field%longname
121 if (PRESENT(atts)) then
141 if (PRESENT(siz)) then
152 if(PRESENT(valid)) then
153 call mpp_get_valid(
field,valid)
156 if(PRESENT(scale)) scale =
field%scale
158 if(present(checksum)) then
160 check_exist = mpp_find_att(
field%Att(:),"checksum")
161 if ( check_exist >= 0 ) then
163 checksum =
field%checksum(1:
size(checksum(:)))
168 end subroutine mpp_get_field_atts
170 !
##################################################################### 171 subroutine mpp_get_axis_atts( axis,
name,
units, longname, cartesian, &
174 type(axistype), intent(in) :: axis
176 character(
len=*), intent(
out), optional :: longname, cartesian
185 if (PRESENT(longname)) longname = axis%longname
186 if (PRESENT(cartesian)) cartesian = axis%cartesian
187 if (PRESENT(compressed)) compressed = axis%compressed
191 if (PRESENT(atts)) then
195 call
mpp_error(FATAL,'attribute array
not large enough in mpp_get_field_atts, axis '
198 atts(
n) = axis%Att(
n)
201 if (PRESENT(natts)) natts =
size(axis%Att(:))
204 end subroutine mpp_get_axis_atts
207 !
##################################################################### 208 subroutine mpp_get_fields(
unit, variables )
211 ! global_atts
is an attribute
type which
is allocated from the
215 type(fieldtype), intent(inout) :: variables(:)
223 call
mpp_error(FATAL,
'MPP_GET_FIELDS: fieldtype not dimensioned properly in calling routine, file ' 233 end subroutine mpp_get_fields
237 !#####################################################################
241 ! global_atts
is an attribute
type which
is allocated from the
245 type(axistype), intent(inout) ::
axes(:)
251 call
mpp_error( FATAL,
'MPP_GET_AXES: invalid unit number, file ' 254 call
mpp_error(FATAL,
'MPP_GET_AXES: axistype not dimensioned properly in calling routine, file ' 272 end subroutine mpp_get_axes
274 !#####################################################################
275 function mpp_get_dimension_length(
unit, dimname, found)
277 character(
len=*), intent(in) :: dimname
278 logical, optional, intent(
out) :: found
279 integer :: mpp_get_dimension_length
285 call
mpp_error( FATAL,
'mpp_get_dimension_length: must first call mpp_io_init.' )
287 call
mpp_error( FATAL,
'mpp_get_dimension_length: invalid unit number, file ' 289 mpp_get_dimension_length = -1
298 if(present(found)) found = found_dim
300 end function mpp_get_dimension_length
302 !#####################################################################
309 call
mpp_error( FATAL,
'MPP_GET_AXES: invalid unit number, file ' 314 end subroutine mpp_get_time_axis
316 !####################################################################
317 function mpp_get_default_calendar( )
322 end function mpp_get_default_calendar
324 !#####################################################################
325 ! <SUBROUTINE NAME=
"mpp_get_times">
327 ! Get file
time data.
330 ! Get file
time data.
333 ! call mpp_get_times(
unit, time_values )
335 ! <IN NAME=
"unit" TYPE=
"integer"> </IN>
336 ! <INOUT NAME=
"time_values" TYPE=
"real(DOUBLE_KIND)" DIM=
"(:)"> </INOUT>
339 subroutine mpp_get_times(
unit, time_values )
344 real, intent(inout) :: time_values(:)
350 call
mpp_error(FATAL,
'MPP_GET_TIMES: invalid unit number, file ' 361 call
mpp_error(FATAL,
'MPP_GET_TIMES: time_values not dimensioned properly in calling routine, file ' 371 end subroutine mpp_get_times
373 !#####################################################################
374 function mpp_get_field_index(
fields,fieldname)
377 character(
len=*) :: fieldname
382 mpp_get_field_index = -1
386 mpp_get_field_index =
n 392 end function mpp_get_field_index
394 !#####################################################################
395 function mpp_get_axis_index(
axes,axisname)
398 character(
len=*) :: axisname
403 mpp_get_axis_index = -1
407 mpp_get_axis_index =
n 413 end function mpp_get_axis_index
415 !#####################################################################
416 function mpp_get_axis_by_name(
unit,axisname)
419 character(
len=*) :: axisname
420 type(axistype) :: mpp_get_axis_by_name
434 end function mpp_get_axis_by_name
436 !#####################################################################
437 function mpp_get_field_size(
field)
440 integer :: mpp_get_field_size(4)
442 mpp_get_field_size = -1
450 end function mpp_get_field_size
453 !#####################################################################
454 function mpp_get_axis_length(axis)
456 type(axistype) :: axis
459 mpp_get_axis_length = axis%
len 462 end function mpp_get_axis_length
464 !#####################################################################
465 function mpp_get_axis_bounds(axis, data,
name)
466 type(axistype), intent(in) :: axis
468 character(
len=*), optional, intent(
out) ::
name 469 logical :: mpp_get_axis_bounds
472 call
mpp_error(FATAL,
'MPP_GET_AXIS_BOUNDS: data array not large enough, axis ' 473 if (.NOT.ASSOCIATED(axis%data_bounds)) then
474 mpp_get_axis_bounds = .
false.
476 mpp_get_axis_bounds = .
true.
477 data(1:axis%
len+1) = axis%data_bounds(:)
479 if(present(
name))
name = trim(axis%name_bounds)
482 end function mpp_get_axis_bounds
484 !#####################################################################
485 subroutine mpp_get_axis_data( axis, data )
487 type(axistype), intent(in) :: axis
492 call
mpp_error(FATAL,
'MPP_GET_AXIS_DATA: data array not large enough, axis ' 493 if (.NOT.ASSOCIATED(axis%data)) then
494 call
mpp_error(NOTE,
'MPP_GET_AXIS_DATA: use mpp_get_times for record dims')
497 data(1:axis%
len) = axis%data
501 end subroutine mpp_get_axis_data
504 !#####################################################################
505 function mpp_get_recdimid(
unit)
517 end function mpp_get_recdimid
519 subroutine mpp_get_iospec(
unit, iospec )
521 character(
len=*), intent(inout) :: iospec
526 !currently
will write to stdout: don
't know how to trap and return as string to iospec 527 call ASSIGN( 'assign -V
f:
'//trim(mpp_file(unit)%name), error ) 530 end subroutine mpp_get_iospec 533 !##################################################################### 534 ! <FUNCTION NAME="mpp_get_ncid"> 536 ! Get netCDF ID of an open file. 539 ! This returns the <TT>ncid</TT> associated with the open file on 540 ! <TT>unit</TT>. It is used in the instance that the user desires to 541 ! perform netCDF calls upon the file that are not provided by the 542 ! <TT>mpp_io_mod</TT> API itself. 547 ! <IN NAME="unit" TYPE="integer"> </IN> 550 function mpp_get_ncid(unit) 551 integer :: mpp_get_ncid 552 integer, intent(in) :: unit 554 mpp_get_ncid = mpp_file(unit)%ncid 556 end function mpp_get_ncid 558 !##################################################################### 559 function mpp_get_axis_id(axis) 560 integer mpp_get_axis_id 561 type(axistype), intent(in) :: axis 562 mpp_get_axis_id = axis%id 564 end function mpp_get_axis_id 566 !##################################################################### 567 function mpp_get_field_id(field) 568 integer mpp_get_field_id 569 type(fieldtype), intent(in) :: field 570 mpp_get_field_id = field%id 572 end function mpp_get_field_id 574 !##################################################################### 575 subroutine mpp_get_unit_range( unit_begin_out, unit_end_out ) 576 integer, intent(out) :: unit_begin_out, unit_end_out 578 unit_begin_out = unit_begin; unit_end_out = unit_end 580 end subroutine mpp_get_unit_range 582 !##################################################################### 583 subroutine mpp_set_unit_range( unit_begin_in, unit_end_in ) 584 integer, intent(in) :: unit_begin_in, unit_end_in 586 if( unit_begin_in.GT.unit_end_in )call mpp_error( FATAL, 'MPP_SET_UNIT_RANGE: unit_begin_in.GT.unit_end_in.
' ) 587 if( unit_begin_in.LT.0 )call mpp_error( FATAL, 'MPP_SET_UNIT_RANGE: unit_begin_in.LT.0.
' ) 588 if( unit_end_in .GT.maxunits )call mpp_error( FATAL, 'MPP_SET_UNIT_RANGE: unit_end_in.GT.
maxunits.
' ) 589 unit_begin = unit_begin_in; unit_end = unit_end_in 591 end subroutine mpp_set_unit_range 593 !##################################################################### 594 subroutine mpp_io_set_stack_size(n) 595 !set the mpp_io_stack variable to be at least n LONG words long 596 integer, intent(in) :: n 597 character(len=10) :: text 599 if( n.GT.mpp_io_stack_size .AND. allocated(mpp_io_stack) )deallocate(mpp_io_stack) 600 if( .NOT.allocated(mpp_io_stack) )then 601 allocate( mpp_io_stack(n) ) 602 mpp_io_stack_size = n 603 write( text,'(i10)
' )n 604 if( pe.EQ.mpp_root_pe() )call mpp_error( NOTE, 'MPP_IO_SET_STACK_SIZE: stack
size set to
'//text//'.
' ) 608 end subroutine mpp_io_set_stack_size 610 !##################################################################### 611 ! based on presence/absence of attributes, defines valid range or missing 612 ! value. For details, see section 8.1 of NetCDF User Guide 613 subroutine mpp_get_valid(f,v) 614 type(fieldtype),intent(in) :: f ! field 615 type(validtype),intent(out) :: v ! validator 617 integer :: irange,imin,imax,ifill,imissing,iscale 618 integer :: valid_T, scale_T ! types of attributes 621 v%min = -HUGE(v%min); v%max = HUGE(v%max) 622 if (f%natt == 0) return 623 ! find indices of relevant attributes 624 irange = mpp_find_att(f%att,'valid_range
') 625 imin = mpp_find_att(f%att,'valid_min
') 626 imax = mpp_find_att(f%att,'valid_max
') 627 ifill = mpp_find_att(f%att,'_FillValue
') 630 ! find the widest type of scale and offset; note that the code 631 ! uses assumption that NetCDF types are arranged in th order of rank, 632 ! that is NF_BYTE < NF_SHORT < NF_INT < NF_FLOAT < NF_DOUBLE 635 if(iscale>0) scale_T = f%att(iscale)%type 636 iscale = mpp_find_att(f%att,'add_offset
') 637 if(iscale>0) scale_T = max(scale_T,f%att(iscale)%type) 640 ! examine possible range attributes 643 v%min = f%att(irange)%fatt(1) 644 v%max = f%att(irange)%fatt(2) 645 valid_T = f%att(irange)%type 646 else if (imax>0.or.imin>0) then 648 v%max = f%att(imax)%fatt(1) 649 valid_T = max(valid_T,f%att(imax)%type) 652 v%min = f%att(imin)%fatt(1) 653 valid_T = max(valid_T,f%att(imin)%type) 655 else if (imissing > 0) then 657 ! here we always scale, since missing_value is supposed to be in 658 ! external representation 659 v%min = f%att(imissing)%fatt(1)*f%scale + f%add 660 else if (ifill>0) then 661 !z1l ifdef is added in to be able to compile without using use_netCDF. 663 ! define min and max according to _FillValue 664 if(f%att(ifill)%fatt(1)>0) then 665 ! if _FillValue is positive, then it defines valid maximum 666 v%max = f%att(ifill)%fatt(1) 668 case (NF_BYTE,NF_SHORT,NF_INT) 671 v%max = nearest(nearest(real(v%max,4),-1.0),-1.0) 673 v%max = nearest(nearest(real(v%max,8),-1.0),-1.0) 675 ! always do the scaling, as the _FillValue is in external 677 v%max = v%max*f%scale + f%add 679 ! if _FillValue is negative or zero, then it defines valid minimum 680 v%min = f%att(ifill)%fatt(1) 682 case (NF_BYTE,NF_SHORT,NF_INT) 685 v%min = nearest(nearest(real(v%min,4),+1.0),+1.0) 687 v%min = nearest(nearest(real(v%min,8),+1.0),+1.0) 689 ! always do the scaling, as the _FillValue is in external 691 v%min = v%min*f%scale + f%add 695 ! If valid_range is the same type as scale_factor (actually the wider of 696 ! scale_factor and add_offset) and this is wider than the external data, then it 697 ! will be interpreted as being in the units of the internal (unpacked) data. 698 ! Otherwise it is in the units of the external (packed) data. 699 ! Note that it is not relevant if we went through the missing_data of _FillValue 700 ! brances, because in this case all irange, imin, and imax are less then 0 701 if(.not.((valid_T == scale_T).and.(scale_T>f%type))) then 702 if(irange>0 .or. imin>0) then 703 v%min = v%min*f%scale + f%add 705 if(irange>0 .or. imax>0) then 706 v%max = v%max*f%scale + f%add 710 end subroutine mpp_get_valid 712 !##################################################################### 713 logical elemental function mpp_is_valid(x, v) 714 real , intent(in) :: x ! real value to be eaxmined 715 type(validtype), intent(in) :: v ! validator 718 mpp_is_valid = (v%min<=x).and.(x<=v%max) 720 mpp_is_valid = x/=v%min 722 end function mpp_is_valid 724 !##################################################################### 725 ! finds an attribute by name in the array; returns -1 if it is not 727 function mpp_find_att(atts, name) 728 integer :: mpp_find_att 729 type(atttype), intent(in) :: atts(:) ! array of attributes 730 character(len=*) :: name ! name of the attributes 736 if (trim(name)==trim(atts(i)%name)) then 741 end function mpp_find_att 742 !##################################################################### 744 ! return the name of an attribute. 745 function mpp_get_att_name(att) 746 type(atttype), intent(in) :: att 747 character(len=len(att%name)) :: mpp_get_att_name 749 mpp_get_att_name = att%name 752 end function mpp_get_att_name 754 !##################################################################### 756 ! return the type of an attribute. 757 function mpp_get_att_type(att) 758 type(atttype), intent(in) :: att 759 integer :: mpp_get_att_type 761 mpp_get_att_type = att%type 764 end function mpp_get_att_type 766 !##################################################################### 768 ! return the length of an attribute. 769 function mpp_get_att_length(att) 770 type(atttype), intent(in) :: att 771 integer :: mpp_get_att_length 773 mpp_get_att_length = att%len 777 end function mpp_get_att_length 779 !##################################################################### 781 ! return the char value of an attribute. 782 function mpp_get_att_char(att) 783 type(atttype), intent(in) :: att 784 character(len=att%len) :: mpp_get_att_char 786 mpp_get_att_char = att%catt 789 end function mpp_get_att_char 791 !##################################################################### 793 ! return the real array value of an attribute. 794 function mpp_get_att_real(att) 795 type(atttype), intent(in) :: att 796 real, dimension(size(att%fatt(:))) :: mpp_get_att_real 798 mpp_get_att_real = att%fatt 801 end function mpp_get_att_real 803 !##################################################################### 805 ! return the real array value of an attribute. 806 function mpp_get_att_real_scalar(att) 807 type(atttype), intent(in) :: att 808 real :: mpp_get_att_real_scalar 810 mpp_get_att_real_scalar = att%fatt(1) 813 end function mpp_get_att_real_scalar 815 !##################################################################### 816 ! return the name of an field 817 function mpp_get_field_name(field) 818 type(fieldtype), intent(in) :: field 819 character(len=len(field%name)) :: mpp_get_field_name 821 mpp_get_field_name = field%name 823 end function mpp_get_field_name 825 !##################################################################### 826 ! return the file name of corresponding unit 827 function mpp_get_file_name(unit) 828 integer, intent(in) :: unit 829 character(len=len(mpp_file(1)%name)) :: mpp_get_file_name 831 mpp_get_file_name = mpp_file(unit)%name 834 end function mpp_get_file_name 836 !#################################################################### 837 ! return if certain file with unit is opened or not 838 function mpp_file_is_opened(unit) 839 integer, intent(in) :: unit 840 logical :: mpp_file_is_opened 842 mpp_file_is_opened = mpp_file(unit)%opened 845 end function mpp_file_is_opened 847 !#################################################################### 848 ! return the attribute value of given field name 849 subroutine mpp_get_field_att_text(unit, fieldname, attname, attvalue) 850 integer, intent(in) :: unit 851 character(len=*), intent(in) :: fieldname, attname 852 character(len=*), intent(out) :: attvalue 853 logical :: found_field, found_att 854 integer :: i, j, length 856 found_field = .false. 858 do i=1,mpp_file(unit)%nvar 859 if( trim(mpp_file(unit)%Var(i)%name) == trim(fieldname)) then 861 do j=1, size(mpp_file(unit)%Var(i)%Att(:)) 862 if( trim(mpp_file(unit)%Var(i)%Att(j)%name) == trim(attname) ) then 864 length = mpp_file(unit)%Var(i)%Att(j)%len 865 if(len(attvalue) .LE. length ) call mpp_error(FATAL, & 866 'mpp_io_util.inc:
length of attvalue
is less than the
length of catt
') 867 attvalue = trim(mpp_file(unit)%Var(i)%Att(j)%catt(1:length)) 875 if(.NOT. found_field) call mpp_error(FATAL,"mpp_io_util.inc: field "//trim(fieldname)// & 876 " does not exist in the file "//trim(mpp_file(unit)%name) ) 877 if(.NOT. found_att) call mpp_error(FATAL,"mpp_io_util.inc: attribute "//trim(attname)//" of field "& 878 //trim(fieldname)// " does not exist in the file "//trim(mpp_file(unit)%name) ) 882 end subroutine mpp_get_field_att_text 885 !#################################################################### 886 ! return mpp_io_nml variable io_clock_on 887 function mpp_io_clock_on() 888 logical :: mpp_io_clock_on 890 mpp_io_clock_on = io_clocks_on 893 end function mpp_io_clock_on 896 function mpp_attribute_exist(field,name) 897 logical :: mpp_attribute_exist 898 type(fieldtype), intent(in) :: field ! The field that you are searching for the attribute. 899 character(len=*), intent(in) :: name ! name of the attributes 901 if(field%natt > 0) then 902 mpp_attribute_exist = ( mpp_find_att(field%Att(:),name) > 0 ) 904 mpp_attribute_exist = .false. 907 end function mpp_attribute_exist 909 !####################################################################### 910 subroutine mpp_dist_io_pelist(ssize,pelist) 911 integer, intent(in) :: ssize ! Stripe size for dist read 912 integer, allocatable, intent(out) :: pelist(:) 913 integer :: i, lsize, ioroot 914 logical :: is_ioroot=.false. 916 ! Did you make a mistake? 917 if(ssize < 1) call mpp_error(FATAL,'mpp_dist_io_pelist: I/O stripe
size < 1
') 919 is_ioroot = mpp_is_dist_ioroot(ssize,ioroot=ioroot,lsize=lsize) 921 ! Did I make a mistake? 922 if(lsize < 1) call mpp_error(FATAL,'mpp_dist_io_pelist:
size of
pelist < 1
') 924 allocate(pelist(lsize)) 926 pelist(i) = ioroot + i - 1 928 end subroutine mpp_dist_io_pelist 930 !####################################################################### 931 logical function mpp_is_dist_ioroot(ssize,ioroot,lsize) 932 integer, intent(in) :: ssize ! Dist io set size 933 integer, intent(out), optional :: ioroot, lsize 934 integer :: pe, npes, mypos, maxpe, d_ioroot, d_lsize, last_ioroot 937 if(ssize < 1) call mpp_error(FATAL,'mpp_is_dist_ioroot: I/O stripe
size < 1
') 939 mpp_is_dist_ioroot = .false. 940 rootpe = mpp_root_pe() 943 mypos = modulo(pe-rootpe,ssize) ! Which PE am I in the io group? 944 d_ioroot = pe - mypos ! What is the io root for the group? 946 maxpe = min(d_ioroot+ssize,npes+rootpe) - 1 ! Handle end case 947 d_lsize = maxpe - d_ioroot + 1 948 if(mod(npes,ssize) == 1)then ! Ensure there are no sets with 1 member 949 last_ioroot = (npes-1) - ssize 950 if(pe >= last_ioroot) then 951 d_ioroot = last_ioroot 955 if(pe == d_ioroot) mpp_is_dist_ioroot = .true. 956 if(PRESENT(ioroot)) ioroot = d_ioroot 957 if(PRESENT(lsize)) lsize = d_lsize 958 end function mpp_is_dist_ioroot
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version will
type(ext_fieldtype), dimension(:), pointer, save, private field
*f90 *************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine MPP_UPDATE_NEST_FINE_2D_(field, nest_domain, wbuffer, ebuffer, sbuffer, nbuffer, &flags, complete, position, extra_halo, name, tile_count) MPP_TYPE_, intent(in) ::field(:,:) type(nest_domain_type), intent(inout) ::nest_domain MPP_TYPE_, intent(inout) ::wbuffer(:,:) MPP_TYPE_, intent(inout) ::ebuffer(:,:) MPP_TYPE_, intent(inout) ::sbuffer(:,:) MPP_TYPE_, intent(inout) ::nbuffer(:,:) integer, intent(in), optional ::flags logical, intent(in), optional ::complete integer, intent(in), optional ::position integer, intent(in), optional ::extra_halo character(len= *), intent(in), optional ::name integer, intent(in), optional ::tile_count MPP_TYPE_ ::field3D(size(field, 1), size(field, 2), 1) MPP_TYPE_ ::wbuffer3D(size(wbuffer, 1), size(wbuffer, 2), 1) MPP_TYPE_ ::ebuffer3D(size(ebuffer, 1), size(ebuffer, 2), 1) MPP_TYPE_ ::sbuffer3D(size(sbuffer, 1), size(sbuffer, 2), 1) MPP_TYPE_ ::nbuffer3D(size(nbuffer, 1), size(nbuffer, 2), 1) pointer(ptr, field3D) pointer(ptr_w, wbuffer3D) pointer(ptr_e, ebuffer3D) pointer(ptr_s, sbuffer3D) pointer(ptr_n, nbuffer3D) ptr=LOC(field) ptr_w=LOC(wbuffer) ptr_e=LOC(ebuffer) ptr_s=LOC(sbuffer) ptr_n=LOC(nbuffer) call mpp_update_nest_fine(field3D, nest_domain, wbuffer3D, ebuffer3D, sbuffer3D, nbuffer3D, &flags, complete, position, extra_halo, name, tile_count) returnend subroutine MPP_UPDATE_NEST_FINE_2D_subroutine MPP_UPDATE_NEST_FINE_3D_(field, nest_domain, wbuffer, sbuffer, ebuffer, nbuffer, &flags, complete, position, extra_halo, name, tile_count) MPP_TYPE_, intent(in) ::field(:,:,:) type(nest_domain_type), intent(inout) ::nest_domain MPP_TYPE_, intent(inout) ::wbuffer(:,:,:) MPP_TYPE_, intent(inout) ::ebuffer(:,:,:) MPP_TYPE_, intent(inout) ::sbuffer(:,:,:) MPP_TYPE_, intent(inout) ::nbuffer(:,:,:) integer, intent(in), optional ::flags logical, intent(in), optional ::complete integer, intent(in), optional ::position integer, intent(in), optional ::extra_halo character(len= *), intent(in), optional ::name integer, intent(in), optional ::tile_count MPP_TYPE_ ::d_type type(nestSpec), pointer ::update=> set_mismatch integer ::tile update_position nbuffersz l_size integer
l_size ! loop over number of fields ke do je do i
integer natt
No description.
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> unit
type(atttype), save, public default_att
subroutine, public copy(self, rhs)
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT end
integer(long), parameter true
type(field_mgr_type), dimension(max_fields), private fields
character(len=32) units
No description.
type(diag_axis_type), dimension(:), allocatable, save axes
integer(long), parameter false
integer ntime
No description.
l_size ! loop over number of fields ke do je do ie to je n if(.NOT. d_comm%R_do_buf(list)) cycle from_pe
logical module_is_initialized
character(len=128) version
l_size ! loop over number of fields ke do je do ie to is
integer, parameter, public global
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> mpp_file(unit)%id
integer nvar
No description.
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version and mpp_transmit will remain !backward compatible intent(inout) MPP_BROADCAST length
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call mpp_error(FATAL, 'MPP_TRANSMIT:you cannot transmit to ANY_PE using MPI.') else if(to_pe.NE.NULL_PE) then !no other valid cases except NULL_PE call mpp_error(FATAL
type(axistype), save, public default_axis
subroutine calendar(year, month, day, hour)
integer sense
No description.
logical function received(this, seqno)
type(axistype), save time_axis
No description.
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> tlevel if(PRESENT(start_in) .AND. PRESENT(axsiz_in)) then if(size(start(! the data domain and compute domain must refer to the subdomain being passed ! In this ! since that attempts to gather all data on PE size(field%axes(:)) axsiz(i)
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT get_len end if return end subroutine MPP_TRANSMIT_ ! MPP_BROADCAST ! subroutine but that doesn t allow !broadcast to a subset of PEs This version and mpp_transmit will remain !backward compatible intent(inout) a
*f90 *************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine MPP_UPDATE_NEST_FINE_2D_(field, nest_domain, wbuffer, ebuffer, sbuffer, nbuffer, &flags, complete, position, extra_halo, name, tile_count) MPP_TYPE_, intent(in) ::field(:,:) type(nest_domain_type), intent(inout) ::nest_domain MPP_TYPE_, intent(inout) ::wbuffer(:,:) MPP_TYPE_, intent(inout) ::ebuffer(:,:) MPP_TYPE_, intent(inout) ::sbuffer(:,:) MPP_TYPE_, intent(inout) ::nbuffer(:,:) integer, intent(in), optional ::flags logical, intent(in), optional ::complete integer, intent(in), optional ::position integer, intent(in), optional ::extra_halo character(len= *), intent(in), optional ::name integer, intent(in), optional ::tile_count MPP_TYPE_ ::field3D(size(field, 1), size(field, 2), 1) MPP_TYPE_ ::wbuffer3D(size(wbuffer, 1), size(wbuffer, 2), 1) MPP_TYPE_ ::ebuffer3D(size(ebuffer, 1), size(ebuffer, 2), 1) MPP_TYPE_ ::sbuffer3D(size(sbuffer, 1), size(sbuffer, 2), 1) MPP_TYPE_ ::nbuffer3D(size(nbuffer, 1), size(nbuffer, 2), 1) pointer(ptr, field3D) pointer(ptr_w, wbuffer3D) pointer(ptr_e, ebuffer3D) pointer(ptr_s, sbuffer3D) pointer(ptr_n, nbuffer3D) ptr=LOC(field) ptr_w=LOC(wbuffer) ptr_e=LOC(ebuffer) ptr_s=LOC(sbuffer) ptr_n=LOC(nbuffer) call mpp_update_nest_fine(field3D, nest_domain, wbuffer3D, ebuffer3D, sbuffer3D, nbuffer3D, &flags, complete, position, extra_halo, name, tile_count) returnend subroutine MPP_UPDATE_NEST_FINE_2D_subroutine MPP_UPDATE_NEST_FINE_3D_(field, nest_domain, wbuffer, sbuffer, ebuffer, nbuffer, &flags, complete, position, extra_halo, name, tile_count) MPP_TYPE_, intent(in) ::field(:,:,:) type(nest_domain_type), intent(inout) ::nest_domain MPP_TYPE_, intent(inout) ::wbuffer(:,:,:) MPP_TYPE_, intent(inout) ::ebuffer(:,:,:) MPP_TYPE_, intent(inout) ::sbuffer(:,:,:) MPP_TYPE_, intent(inout) ::nbuffer(:,:,:) integer, intent(in), optional ::flags logical, intent(in), optional ::complete integer, intent(in), optional ::position integer, intent(in), optional ::extra_halo character(len= *), intent(in), optional ::name integer, intent(in), optional ::tile_count MPP_TYPE_ ::d_type type(nestSpec), pointer ::update=> dimension(MAX_DOMAIN_FIELDS)
integer, dimension(:), allocatable pelist
*f90 *************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If not
real missing_value
No description.
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> time_level
real(fp), parameter scale_factor
subroutine, public some(xmap, some_arr, grid_id)
character(len=len(cs)) function lowercase(cs)
integer, parameter, public information
integer ndim
No description.