This subroutine sets the open face lengths at selected points to restrict passages to their observed widths from a list read from a file.
820 type(dyn_horgrid_type),
intent(inout) :: G
821 type(param_file_type),
intent(in) :: param_file
822 type(unit_scale_type),
optional,
intent(in) :: US
825 character(len=120),
pointer,
dimension(:) :: lines => null()
826 character(len=120) :: line
827 character(len=200) :: filename, chan_file, inputdir, mesg
828 character(len=40) :: mdl =
"reset_face_lengths_list" 829 real,
pointer,
dimension(:,:) :: &
830 u_lat => null(), u_lon => null(), v_lat => null(), v_lon => null()
831 real,
pointer,
dimension(:) :: &
832 u_width => null(), v_width => null()
841 logical :: found_u, found_v
842 logical :: unit_in_use
843 integer :: ios, iounit, isu, isv
844 integer :: last, num_lines, nl_read, ln, npt, u_pt, v_pt
845 integer :: i, j, isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
846 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
847 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
849 call calltree_enter(trim(mdl)//
"(), MOM_shared_initialization.F90")
850 m_to_l = 1.0 ;
if (
present(us)) m_to_l = us%m_to_L
851 l_to_m = 1.0 ;
if (
present(us)) l_to_m = us%L_to_m
853 call get_param(param_file, mdl,
"CHANNEL_LIST_FILE", chan_file, &
854 "The file from which the list of narrowed channels is read.", &
855 default=
"MOM_channel_list")
856 call get_param(param_file, mdl,
"INPUTDIR", inputdir, default=
".")
857 inputdir = slasher(inputdir)
858 filename = trim(inputdir)//trim(chan_file)
859 call log_param(param_file, mdl,
"INPUTDIR/CHANNEL_LIST_FILE", filename)
860 call get_param(param_file, mdl,
"CHANNEL_LIST_360_LON_CHECK", check_360, &
861 "If true, the channel configuration list works for any "//&
862 "longitudes in the range of -360 to 360.", default=.true.)
864 if (is_root_pe())
then 866 if (.not.file_exists(filename))
call mom_error(fatal, &
867 " reset_face_lengths_list: Unable to open "//trim(filename))
871 INQUIRE(iounit,opened=unit_in_use) ;
if (.not.unit_in_use)
exit 873 if (iounit >= 512)
call mom_error(fatal, &
874 "reset_face_lengths_list: No unused file unit could be found.")
877 open(iounit, file=trim(filename), access=
'SEQUENTIAL', &
878 form=
'FORMATTED', action=
'READ', position=
'REWIND', iostat=ios)
879 if (ios /= 0)
call mom_error(fatal, &
880 "reset_face_lengths_list: Error opening "//trim(filename))
883 call read_face_length_list(iounit, filename, num_lines, lines)
886 len_lon = 360.0 ;
if (g%len_lon > 0.0) len_lon = g%len_lon
887 len_lat = 180.0 ;
if (g%len_lat > 0.0) len_lat = g%len_lat
889 call broadcast(num_lines, root_pe())
891 if (num_lines > 0)
then 892 allocate (lines(num_lines))
893 if (num_lines > 0)
then 894 allocate(u_lat(2,num_lines)) ; u_lat(:,:) = -1e34
895 allocate(u_lon(2,num_lines)) ; u_lon(:,:) = -1e34
896 allocate(u_width(num_lines)) ; u_width(:) = -1e34
898 allocate(v_lat(2,num_lines)) ; v_lat(:,:) = -1e34
899 allocate(v_lon(2,num_lines)) ; v_lon(:,:) = -1e34
900 allocate(v_width(num_lines)) ; v_width(:) = -1e34
904 if (is_root_pe())
then 905 call read_face_length_list(iounit, filename, nl_read, lines)
906 if (nl_read /= num_lines) &
907 call mom_error(fatal,
'reset_face_lengths_list : Found different '// &
908 'number of valid lines on second reading of '//trim(filename))
909 close(iounit) ; iounit = -1
913 call broadcast(lines, 120, root_pe())
919 found_u = .false.; found_v = .false.
920 isu = index(uppercase(line),
"U_WIDTH" );
if (isu > 0) found_u = .true.
921 isv = index(uppercase(line),
"V_WIDTH" );
if (isv > 0) found_v = .true.
926 read(line(isu+8:),*) u_lon(1:2,u_pt), u_lat(1:2,u_pt), u_width(u_pt)
927 if (is_root_pe())
then 929 if ((abs(u_lon(1,u_pt)) > len_lon) .or. (abs(u_lon(2,u_pt)) > len_lon)) &
930 call mom_error(warning,
"reset_face_lengths_list : Out-of-bounds "//&
931 "u-longitude found when reading line "//trim(line)//
" from file "//&
933 if ((abs(u_lat(1,u_pt)) > len_lat) .or. (abs(u_lat(2,u_pt)) > len_lat)) &
934 call mom_error(warning,
"reset_face_lengths_list : Out-of-bounds "//&
935 "u-latitude found when reading line "//trim(line)//
" from file "//&
938 if (u_lat(1,u_pt) > u_lat(2,u_pt)) &
939 call mom_error(warning,
"reset_face_lengths_list : Out-of-order "//&
940 "u-face latitudes found when reading line "//trim(line)//
" from file "//&
942 if (u_lon(1,u_pt) > u_lon(2,u_pt)) &
943 call mom_error(warning,
"reset_face_lengths_list : Out-of-order "//&
944 "u-face longitudes found when reading line "//trim(line)//
" from file "//&
946 if (u_width(u_pt) < 0.0) &
947 call mom_error(warning,
"reset_face_lengths_list : Negative "//&
948 "u-width found when reading line "//trim(line)//
" from file "//&
951 elseif (found_v)
then 953 read(line(isv+8:),*) v_lon(1:2,v_pt), v_lat(1:2,v_pt), v_width(v_pt)
954 if (is_root_pe())
then 956 if ((abs(v_lon(1,v_pt)) > len_lon) .or. (abs(v_lon(2,v_pt)) > len_lon)) &
957 call mom_error(warning,
"reset_face_lengths_list : Out-of-bounds "//&
958 "v-longitude found when reading line "//trim(line)//
" from file "//&
960 if ((abs(v_lat(1,v_pt)) > len_lat) .or. (abs(v_lat(2,v_pt)) > len_lat)) &
961 call mom_error(warning,
"reset_face_lengths_list : Out-of-bounds "//&
962 "v-latitude found when reading line "//trim(line)//
" from file "//&
965 if (v_lat(1,v_pt) > v_lat(2,v_pt)) &
966 call mom_error(warning,
"reset_face_lengths_list : Out-of-order "//&
967 "v-face latitudes found when reading line "//trim(line)//
" from file "//&
969 if (v_lon(1,v_pt) > v_lon(2,v_pt)) &
970 call mom_error(warning,
"reset_face_lengths_list : Out-of-order "//&
971 "v-face longitudes found when reading line "//trim(line)//
" from file "//&
973 if (v_width(v_pt) < 0.0) &
974 call mom_error(warning,
"reset_face_lengths_list : Negative "//&
975 "v-width found when reading line "//trim(line)//
" from file "//&
984 do j=jsd,jed ;
do i=isdb,iedb
985 lat = g%geoLatCu(i,j) ; lon = g%geoLonCu(i,j)
986 if (check_360)
then ; lon_p = lon+len_lon ; lon_m = lon-len_lon
987 else ; lon_p = lon ; lon_m = lon ;
endif 990 if (((lat >= u_lat(1,npt)) .and. (lat <= u_lat(2,npt))) .and. &
991 (((lon >= u_lon(1,npt)) .and. (lon <= u_lon(2,npt))) .or. &
992 ((lon_p >= u_lon(1,npt)) .and. (lon_p <= u_lon(2,npt))) .or. &
993 ((lon_m >= u_lon(1,npt)) .and. (lon_m <= u_lon(2,npt)))) )
then 995 g%dy_Cu(i,j) = g%mask2dCu(i,j) * m_to_l*min(l_to_m*g%dyCu(i,j), max(u_width(npt), 0.0))
996 if (j>=g%jsc .and. j<=g%jec .and. i>=g%isc .and. i<=g%iec)
then 997 if ( g%mask2dCu(i,j) == 0.0 )
then 998 write(*,
'(A,2F8.2,A,4F8.2,A)')
"read_face_lengths_list : G%mask2dCu=0 at ",lat,lon,
" (",&
999 u_lat(1,npt), u_lat(2,npt), u_lon(1,npt), u_lon(2,npt),
") so grid metric is unmodified." 1001 write(*,
'(A,2F8.2,A,4F8.2,A5,F9.2,A1)') &
1002 "read_face_lengths_list : Modifying dy_Cu gridpoint at ",lat,lon,
" (",&
1003 u_lat(1,npt), u_lat(2,npt), u_lon(1,npt), u_lon(2,npt),
") to ",l_to_m*g%dy_Cu(i,j),
"m" 1009 g%areaCu(i,j) = g%dxCu(i,j) * g%dy_Cu(i,j)
1010 g%IareaCu(i,j) = 0.0
1011 if (g%areaCu(i,j) > 0.0) g%IareaCu(i,j) = g%mask2dCu(i,j) / (g%areaCu(i,j))
1014 do j=jsdb,jedb ;
do i=isd,ied
1015 lat = g%geoLatCv(i,j) ; lon = g%geoLonCv(i,j)
1016 if (check_360)
then ; lon_p = lon+len_lon ; lon_m = lon-len_lon
1017 else ; lon_p = lon ; lon_m = lon ;
endif 1020 if (((lat >= v_lat(1,npt)) .and. (lat <= v_lat(2,npt))) .and. &
1021 (((lon >= v_lon(1,npt)) .and. (lon <= v_lon(2,npt))) .or. &
1022 ((lon_p >= v_lon(1,npt)) .and. (lon_p <= v_lon(2,npt))) .or. &
1023 ((lon_m >= v_lon(1,npt)) .and. (lon_m <= v_lon(2,npt)))) )
then 1024 g%dx_Cv(i,j) = g%mask2dCv(i,j) * m_to_l*min(l_to_m*g%dxCv(i,j), max(v_width(npt), 0.0))
1025 if (i>=g%isc .and. i<=g%iec .and. j>=g%jsc .and. j<=g%jec)
then 1026 if ( g%mask2dCv(i,j) == 0.0 )
then 1027 write(*,
'(A,2F8.2,A,4F8.2,A)')
"read_face_lengths_list : G%mask2dCv=0 at ",lat,lon,
" (",&
1028 v_lat(1,npt), v_lat(2,npt), v_lon(1,npt), v_lon(2,npt),
") so grid metric is unmodified." 1030 write(*,
'(A,2F8.2,A,4F8.2,A5,F9.2,A1)') &
1031 "read_face_lengths_list : Modifying dx_Cv gridpoint at ",lat,lon,
" (",&
1032 v_lat(1,npt), v_lat(2,npt), v_lon(1,npt), v_lon(2,npt),
") to ",l_to_m*g%dx_Cv(i,j),
"m" 1038 g%areaCv(i,j) = g%dyCv(i,j) * g%dx_Cv(i,j)
1039 g%IareaCv(i,j) = 0.0
1040 if (g%areaCv(i,j) > 0.0) g%IareaCv(i,j) = g%mask2dCv(i,j) / (g%areaCv(i,j))
1043 if (num_lines > 0)
then 1044 deallocate(u_lat) ;
deallocate(u_lon) ;
deallocate(u_width)
1045 deallocate(v_lat) ;
deallocate(v_lon) ;
deallocate(v_width)
1048 call calltree_leave(trim(mdl)//
'()')