23 subroutine initialize_diagnostic_columns_ &
24 (module, num_diag_pts_latlon, num_diag_pts_ij, &
25 global_i , global_j , global_lat_latlon, &
26 global_lon_latlon, lonb_in, latb_in, &
27 do_column_diagnostics, &
28 diag_lon, diag_lat, diag_i, diag_j, diag_units)
37 character(len=*),
intent(in) :: module
38 integer,
intent(in) :: num_diag_pts_latlon
40 integer,
intent(in) :: num_diag_pts_ij
42 integer,
dimension(:),
intent(in) :: global_i
43 integer,
dimension(:),
intent(in) :: global_j
44 real(FMS_CD_KIND_),
dimension(:),
intent(in) :: global_lat_latlon
45 real(FMS_CD_KIND_),
dimension(:),
intent(in) :: global_lon_latlon
46 real(FMS_CD_KIND_),
dimension(:,:),
intent(in) :: lonb_in, latb_in
47 logical,
dimension(:,:),
intent(out) :: do_column_diagnostics
48 integer,
dimension(:),
intent(inout) :: diag_i
49 integer,
dimension(:),
intent(inout) :: diag_j
50 real(FMS_CD_KIND_),
dimension(:),
intent(out) :: diag_lat
51 real(FMS_CD_KIND_),
dimension(:),
intent(out) :: diag_lon
52 integer,
dimension(:),
intent(out) :: diag_units
84 real(FMS_CD_KIND_),
dimension(size(diag_i,1)) :: global_lat
85 real(FMS_CD_KIND_),
dimension(size(diag_i,1)) :: global_lon
86 real(FMS_CD_KIND_),
dimension(size(latb_in,1)-1, size(latb_in,2)-1) :: &
87 distance, distance_x, distance_y, &
88 distance_x2, distance2
89 real(FMS_CD_KIND_),
dimension(size(latb_in,1), size(latb_in,2)) :: latb_deg
90 real(FMS_CD_KIND_),
dimension(size(lonb_in,1), size(lonb_in,2)) :: lonb_deg
91 real(FMS_CD_KIND_) :: dellat, dellon
92 real(FMS_CD_KIND_) :: latb_max, latb_min, lonb_max, lonb_min
94 integer :: num_diag_pts
98 real(FMS_CD_KIND_) :: ref_lat
99 real(FMS_CD_KIND_) :: current_distance
100 character(len=8) :: char
101 character(len=FMS_FILE_LEN) :: filename
102 logical :: allow_ij_input
106 integer,
parameter :: lkind=fms_cd_kind_
107 real(FMS_CD_KIND_) :: tmp
121 if (.not. module_is_initialized)
call column_diagnostics_init
127 latb_deg = real( real(latb_in,r8_kind)*radian, fms_cd_kind_)
128 lonb_deg = real( real(lonb_in,r8_kind)*radian, fms_cd_kind_ )
129 dellat = latb_in(1,2) - latb_in(1,1)
130 dellon = lonb_in(2,1) - lonb_in(1,1)
131 latb_max = maxval(latb_deg(:,:))
132 latb_min = minval(latb_deg(:,:))
133 lonb_max = maxval(lonb_deg(:,:))
134 lonb_min = minval(lonb_deg(:,:))
135 if (lonb_min < 10.0_lkind .or. lonb_max > 350.0_lkind)
then
137 lonb_max = 360.0_lkind
140 allow_ij_input = .true.
141 ref_lat = latb_in(1,1)
142 do i =2,
size(latb_in,1)
143 if (latb_in(i,1) /= ref_lat)
then
144 allow_ij_input = .false.
149 if ( .not. allow_ij_input .and. num_diag_pts_ij /= 0)
then
150 call error_mesg (
'column_diagnostics_mod', &
151 'cannot specify column diagnostics column with (i,j) &
152 &coordinates when using cubed sphere -- must specify &
153 & lat/lon coordinates', fatal)
162 do_column_diagnostics = .false.
166 diag_lat(:) = -999.0_lkind
167 diag_lon(:) = -999.0_lkind
168 num_diag_pts =
size(diag_i(:))
173 do nn = 1, num_diag_pts_latlon
174 global_lat(nn) = global_lat_latlon(nn)
175 global_lon(nn) = global_lon_latlon(nn)
178 do nn = 1, num_diag_pts_ij
179 tmp = (-0.5_lkind*acos(-1.0_lkind) + 0.5_lkind*dellat) + real(global_j(nn)-1,fms_cd_kind_)*dellat
180 global_lat(nn+num_diag_pts_latlon) = real( real(tmp,r8_kind)*radian, fms_cd_kind_ )
181 tmp = 0.5_lkind*dellon + real(global_i(nn)-1,fms_cd_kind_)*dellon
182 global_lon(nn+num_diag_pts_latlon) = real( real(tmp,r8_kind)*radian, fms_cd_kind_ )
195 if (global_lon(nn) >= 0.0_lkind .and. &
196 global_lon(nn) <= 360.0_lkind)
then
198 call error_mesg (
'column_diagnostics_mod', &
199 ' invalid longitude', fatal)
201 if (global_lat(nn) >= -90.0_lkind .and. &
202 global_lat(nn) <= 90.0_lkind)
then
204 call error_mesg (
'column_diagnostics_mod', &
205 ' invalid latitude', fatal)
214 if (global_lat(nn) .ge. latb_min .and. &
215 global_lat(nn) .le. latb_max)
then
216 if (global_lon(nn) .ge. lonb_min .and.&
217 global_lon(nn) .le. lonb_max)
then
218 do j=1,
size(latb_deg,2) - 1
219 do i=1,
size(lonb_deg,1) - 1
220 distance_y(i,j) = abs(global_lat(nn) - latb_deg(i,j))
221 distance_x(i,j) = abs(global_lon(nn) - lonb_deg(i,j))
222 distance_x2(i,j) = abs((global_lon(nn)-360.0_lkind) - lonb_deg(i,j))
223 distance(i,j) = (global_lat(nn)-latb_deg(i,j))**2 + (global_lon(nn)-lonb_deg(i,j))**2
224 distance2(i,j) = (global_lat(nn)-latb_deg(i,j))**2 + ((global_lon(nn)-360.0_lkind) - lonb_deg(i,j))**2
235 current_distance = distance(1,1)
236 do j=1,
size(latb_deg,2) - 1
237 do i=1,
size(lonb_deg,1) - 1
238 if (distance_x(i,j) <= real(crit_xdistance,fms_cd_kind_) .and. &
239 distance_y(i,j) <= real(crit_ydistance,fms_cd_kind_))
then
240 if (distance(i,j) < current_distance)
then
241 current_distance = distance(i,j)
242 do_column_diagnostics(i,j) = .true.
245 diag_lon(nn) = lonb_deg(i,j)
246 diag_lat(nn) = latb_deg(i,j)
254 if (distance_x2(i,j)<= real(crit_xdistance,fms_cd_kind_) .and. &
255 distance_y(i,j) <= real(crit_ydistance,fms_cd_kind_))
then
256 if (distance2(i,j) < current_distance)
then
257 current_distance = distance2(i,j)
258 do_column_diagnostics(i,j) = .true.
261 diag_lon(nn) = lonb_deg(i,j)
262 diag_lat(nn) = latb_deg(i,j)
274 write (char,
'(i2)') nn
275 filename = trim(module) //
'_point' // &
276 trim(adjustl(char)) //
'.out'
278 write( filename,
'(a,i6.6)' )trim(filename)//
'.',
mpp_pe()-mpp_root_pe()
280 write( filename,
'(a,i4.4)' )trim(filename)//
'.',
mpp_pe()-mpp_root_pe()
282 open(newunit=diag_units(nn), file=trim(filename), action=
'WRITE', position=
'rewind', iostat=io)
283 if(io/=0)
call error_mesg (
'column_diagnostics_mod',
'Error in opening file '//trim(filename), fatal)
292 end subroutine initialize_diagnostic_columns_
301 subroutine column_diagnostics_header_ &
302 (module, diag_unit, time, nn, diag_lon, &
303 diag_lat, diag_i, diag_j)
312 character(len=*),
intent(in) :: module
313 type(time_type),
intent(in) :: Time
314 integer,
intent(in) :: diag_unit
315 integer,
intent(in) :: nn
316 real(FMS_CD_KIND_),
dimension(:),
intent(in) :: diag_lon
317 real(FMS_CD_KIND_),
dimension(:),
intent(in) :: diag_lat
318 integer,
dimension(:),
intent(in) :: diag_i
319 integer,
dimension(:),
intent(in) :: diag_j
345 character(len=9) :: mon
346 character(len=64) :: header
358 if (.not. module_is_initialized)
call column_diagnostics_init
364 call get_date (time, year, month, day, hour, minute, second)
365 mon = month_name(month)
371 write (diag_unit,
'(a)')
' '
372 write (diag_unit,
'(a)')
' '
373 write (diag_unit,
'(a)') &
374 '======================================================'
375 write (diag_unit,
'(a)')
' '
376 header =
' PRINTING ' //
module //
' DIAGNOSTICS'
377 write (diag_unit,
'(a)') header
378 write (diag_unit,
'(a)')
' '
379 write (diag_unit,
'(a, i6,2x, a,i4,i4,i4,i4)')
' time stamp:', &
380 year, trim(mon), day, &
382 write (diag_unit,
'(a, i4)') &
383 ' DIAGNOSTIC POINT COORDINATES, point #', nn
384 write (diag_unit,
'(a)')
' '
385 write (diag_unit,
'(a,f8.3,a,f8.3)')
' longitude = ', &
386 diag_lon(nn),
' latitude = ', diag_lat(nn)
387 write (diag_unit,
'(a, i6, a,i6,a,i6)') &
388 ' on processor # ',
mpp_pe(), &
389 ' : processor i =', diag_i(nn), &
390 ' , processor j =', diag_j(nn)
391 write (diag_unit,
'(a)')
' '
395 end subroutine column_diagnostics_header_
integer function mpp_npes()
Returns processor count for current pelist.
integer function mpp_pe()
Returns processor ID.