24subroutine initialize_diagnostic_columns_ &
25 (module, num_diag_pts_latlon, num_diag_pts_ij, &
26 global_i , global_j , global_lat_latlon, &
27 global_lon_latlon, lonb_in, latb_in, &
28 do_column_diagnostics, &
29 diag_lon, diag_lat, diag_i, diag_j, diag_units)
38character(len=*),
intent(in) :: module
39integer,
intent(in) :: num_diag_pts_latlon
41integer,
intent(in) :: num_diag_pts_ij
43integer,
dimension(:),
intent(in) :: global_i
44integer,
dimension(:),
intent(in) :: global_j
45real(FMS_CD_KIND_),
dimension(:),
intent(in) :: global_lat_latlon
46real(FMS_CD_KIND_),
dimension(:),
intent(in) :: global_lon_latlon
47real(FMS_CD_KIND_),
dimension(:,:),
intent(in) :: lonb_in, latb_in
48logical,
dimension(:,:),
intent(out) :: do_column_diagnostics
49integer,
dimension(:),
intent(inout) :: diag_i
50integer,
dimension(:),
intent(inout) :: diag_j
51real(FMS_CD_KIND_),
dimension(:),
intent(out) :: diag_lat
52real(FMS_CD_KIND_),
dimension(:),
intent(out) :: diag_lon
53integer,
dimension(:),
intent(out) :: diag_units
85 real(FMS_CD_KIND_),
dimension(size(diag_i,1)) :: global_lat
86 real(FMS_CD_KIND_),
dimension(size(diag_i,1)) :: global_lon
87 real(FMS_CD_KIND_),
dimension(size(latb_in,1)-1, size(latb_in,2)-1) :: &
88 distance, distance_x, distance_y, &
89 distance_x2, distance2
90 real(FMS_CD_KIND_),
dimension(size(latb_in,1), size(latb_in,2)) :: latb_deg
91 real(FMS_CD_KIND_),
dimension(size(lonb_in,1), size(lonb_in,2)) :: lonb_deg
92 real(FMS_CD_KIND_) :: dellat, dellon
93 real(FMS_CD_KIND_) :: latb_max, latb_min, lonb_max, lonb_min
95 integer :: num_diag_pts
99 real(FMS_CD_KIND_) :: ref_lat
100 real(FMS_CD_KIND_) :: current_distance
101 character(len=8) :: char
102 character(len=FMS_FILE_LEN) :: filename
103 logical :: allow_ij_input
107 integer,
parameter :: lkind=fms_cd_kind_
108 real(FMS_CD_KIND_) :: tmp
122 if (.not. module_is_initialized)
call column_diagnostics_init
128 latb_deg = real( real(latb_in,r8_kind)*radian, fms_cd_kind_)
129 lonb_deg = real( real(lonb_in,r8_kind)*radian, fms_cd_kind_ )
130 dellat = latb_in(1,2) - latb_in(1,1)
131 dellon = lonb_in(2,1) - lonb_in(1,1)
132 latb_max = maxval(latb_deg(:,:))
133 latb_min = minval(latb_deg(:,:))
134 lonb_max = maxval(lonb_deg(:,:))
135 lonb_min = minval(lonb_deg(:,:))
136 if (lonb_min < 10.0_lkind .or. lonb_max > 350.0_lkind)
then
138 lonb_max = 360.0_lkind
141 allow_ij_input = .true.
142 ref_lat = latb_in(1,1)
143 do i =2,
size(latb_in,1)
144 if (latb_in(i,1) /= ref_lat)
then
145 allow_ij_input = .false.
150 if ( .not. allow_ij_input .and. num_diag_pts_ij /= 0)
then
151 call error_mesg (
'column_diagnostics_mod', &
152 'cannot specify column diagnostics column with (i,j) &
153 &coordinates when using cubed sphere -- must specify &
154 & lat/lon coordinates', fatal)
163 do_column_diagnostics = .false.
167 diag_lat(:) = -999.0_lkind
168 diag_lon(:) = -999.0_lkind
169 num_diag_pts =
size(diag_i(:))
174 do nn = 1, num_diag_pts_latlon
175 global_lat(nn) = global_lat_latlon(nn)
176 global_lon(nn) = global_lon_latlon(nn)
179 do nn = 1, num_diag_pts_ij
180 tmp = (-0.5_lkind*acos(-1.0_lkind) + 0.5_lkind*dellat) + real(global_j(nn)-1,fms_cd_kind_)*dellat
181 global_lat(nn+num_diag_pts_latlon) = real( real(tmp,r8_kind)*radian, fms_cd_kind_ )
182 tmp = 0.5_lkind*dellon + real(global_i(nn)-1,fms_cd_kind_)*dellon
183 global_lon(nn+num_diag_pts_latlon) = real( real(tmp,r8_kind)*radian, fms_cd_kind_ )
196 if (global_lon(nn) >= 0.0_lkind .and. &
197 global_lon(nn) <= 360.0_lkind)
then
199 call error_mesg (
'column_diagnostics_mod', &
200 ' invalid longitude', fatal)
202 if (global_lat(nn) >= -90.0_lkind .and. &
203 global_lat(nn) <= 90.0_lkind)
then
205 call error_mesg (
'column_diagnostics_mod', &
206 ' invalid latitude', fatal)
215 if (global_lat(nn) .ge. latb_min .and. &
216 global_lat(nn) .le. latb_max)
then
217 if (global_lon(nn) .ge. lonb_min .and.&
218 global_lon(nn) .le. lonb_max)
then
219 do j=1,
size(latb_deg,2) - 1
220 do i=1,
size(lonb_deg,1) - 1
221 distance_y(i,j) = abs(global_lat(nn) - latb_deg(i,j))
222 distance_x(i,j) = abs(global_lon(nn) - lonb_deg(i,j))
223 distance_x2(i,j) = abs((global_lon(nn)-360.0_lkind) - lonb_deg(i,j))
224 distance(i,j) = (global_lat(nn)-latb_deg(i,j))**2 + (global_lon(nn)-lonb_deg(i,j))**2
225 distance2(i,j) = (global_lat(nn)-latb_deg(i,j))**2 + ((global_lon(nn)-360.0_lkind) - lonb_deg(i,j))**2
236 current_distance = distance(1,1)
237 do j=1,
size(latb_deg,2) - 1
238 do i=1,
size(lonb_deg,1) - 1
239 if (distance_x(i,j) <= real(crit_xdistance,fms_cd_kind_) .and. &
240 distance_y(i,j) <= real(crit_ydistance,fms_cd_kind_))
then
241 if (distance(i,j) < current_distance)
then
242 current_distance = distance(i,j)
243 do_column_diagnostics(i,j) = .true.
246 diag_lon(nn) = lonb_deg(i,j)
247 diag_lat(nn) = latb_deg(i,j)
255 if (distance_x2(i,j)<= real(crit_xdistance,fms_cd_kind_) .and. &
256 distance_y(i,j) <= real(crit_ydistance,fms_cd_kind_))
then
257 if (distance2(i,j) < current_distance)
then
258 current_distance = distance2(i,j)
259 do_column_diagnostics(i,j) = .true.
262 diag_lon(nn) = lonb_deg(i,j)
263 diag_lat(nn) = latb_deg(i,j)
275 write (char,
'(i2)') nn
276 filename = trim(module) //
'_point' // &
277 trim(adjustl(char)) //
'.out'
278 if(mpp_npes() > 10000)
then
279 write( filename,
'(a,i6.6)' )trim(filename)//
'.', mpp_pe()-mpp_root_pe()
281 write( filename,
'(a,i4.4)' )trim(filename)//
'.', mpp_pe()-mpp_root_pe()
283 open(newunit=diag_units(nn), file=trim(filename), action=
'WRITE', position=
'rewind', iostat=io)
284 if(io/=0)
call error_mesg (
'column_diagnostics_mod',
'Error in opening file '//trim(filename), fatal)
293end subroutine initialize_diagnostic_columns_
302subroutine column_diagnostics_header_ &
303 (module, diag_unit, time, nn, diag_lon, &
304 diag_lat, diag_i, diag_j)
313character(len=*),
intent(in) :: module
314type(time_type),
intent(in) :: Time
315integer,
intent(in) :: diag_unit
316integer,
intent(in) :: nn
317real(FMS_CD_KIND_),
dimension(:),
intent(in) :: diag_lon
318real(FMS_CD_KIND_),
dimension(:),
intent(in) :: diag_lat
319integer,
dimension(:),
intent(in) :: diag_i
320integer,
dimension(:),
intent(in) :: diag_j
346 character(len=9) :: mon
347 character(len=64) :: header
359 if (.not. module_is_initialized)
call column_diagnostics_init
365 call get_date (time, year, month, day, hour, minute, second)
366 mon = month_name(month)
372 write (diag_unit,
'(a)')
' '
373 write (diag_unit,
'(a)')
' '
374 write (diag_unit,
'(a)') &
375 '======================================================'
376 write (diag_unit,
'(a)')
' '
377 header =
' PRINTING ' //
module //
' DIAGNOSTICS'
378 write (diag_unit,
'(a)') header
379 write (diag_unit,
'(a)')
' '
380 write (diag_unit,
'(a, i6,2x, a,i4,i4,i4,i4)')
' time stamp:', &
381 year, trim(mon), day, &
383 write (diag_unit,
'(a, i4)') &
384 ' DIAGNOSTIC POINT COORDINATES, point #', nn
385 write (diag_unit,
'(a)')
' '
386 write (diag_unit,
'(a,f8.3,a,f8.3)')
' longitude = ', &
387 diag_lon(nn),
' latitude = ', diag_lat(nn)
388 write (diag_unit,
'(a, i6, a,i6,a,i6)') &
389 ' on processor # ', mpp_pe(), &
390 ' : processor i =', diag_i(nn), &
391 ' , processor j =', diag_j(nn)
392 write (diag_unit,
'(a)')
' '
396end subroutine column_diagnostics_header_