3 ! This program computes the 3d height field for the UKMO data. The heights
4 ! are constant in time, and are a function only of the topography and a few
5 ! constants. There are several UKMO data sets available, denoted by the
6 ! different numbers of vertical levels. An input file defines the required
7 ! information for each of these data sets.
13 use misc_definitions_module
20 character (len=19) :: valid_date, temp_date, output_date
21 character (len=128) :: input_name
22 type (met_data) :: temp_data, soilhgt_data, height_data
24 integer :: model_levels , first_constant_r_rho_level , k_loop , j_loop , i_loop , temp_count , date_loop
25 real :: z_top_of_model , etac
26 real, dimension(:) , allocatable :: eta
27 real , dimension(:,:) , allocatable :: soil_hold
28 logical :: still_more_dates_to_process
30 call get_namelist_params()
32 call set_debug_level(WARN)
34 input_name = fg_name(1)
36 call geth_newdate(valid_date, trim(start_date(1)), 0 )
39 write(temp_date,'(a19)') valid_date(1:10)//'_'//valid_date(12:19)
40 write(output_date,'(a19)') valid_date(1:10)//'_'//valid_date(12:19)
42 ! Do this twice. The first time is to find out how many levels of
43 ! 3d fields there are. Why? The data from UKMO has *some* of the
44 ! levels, just not all. So we can compute the height field, but we
45 ! are not allowed to just spit out 70 levels.
47 ! Initialize the module for reading in the met fields
48 call read_met_init(trim(input_name), .false., temp_date(1:13), istatus)
50 if (istatus == 0) then
51 call mprintf(.true.,STDOUT,'Reading from %s at time %s', s1=input_name, s2=temp_date(1:13))
53 ! Process all fields and levels from the current file; read_next_met_field()
54 ! will return a non-zero status when there are no more fields to be read.
56 just_temp : do while (istatus == 0)
58 call read_next_met_field(temp_data, istatus)
60 if (istatus == 0) then
62 if (trim(temp_data%field) == 'TT' .and. temp_data%xlvl /= 200100.) then
63 temp_count = temp_count + 1
64 else if (trim(temp_data%field) == 'SOILHGT' .and. temp_data%xlvl == 200100.) then
65 allocate ( soil_hold(temp_data%nx,temp_data%ny) )
66 do j_loop = 1 , temp_data%ny
67 do i_loop = 1 , temp_data%nx
68 soil_hold(i_loop,j_loop) = temp_data%slab(i_loop,j_loop)
73 deallocate ( temp_data%slab )
77 call mprintf(.true.,STDOUT,'Total number of TT levels, excluding 200100 = %i' , i1=temp_count)
82 call mprintf(.true.,ERROR,'Problem opening %s at time %s', s1=input_name, s2=temp_date(1:13))
85 ! Now we are doing this the second time. We know how many temp levels there are, temp_count,
86 ! so we will use the same number for height.
88 ! Initialize the module for reading in the met fields - again!
89 call read_met_init(trim(input_name), .false., temp_date(1:13), istatus)
91 if (istatus == 0) then
92 call mprintf(.true.,STDOUT,'Reading from %s at time %s', s1=input_name, s2=temp_date(1:13))
94 ! Process all fields and levels from the current file; read_next_met_field()
95 ! will return a non-zero status when there are no more fields to be read.
96 all_fields : do while (istatus == 0)
99 if ( associated ( soilhgt_data%slab ) ) then
100 deallocate ( soilhgt_data%slab )
102 call read_next_met_field(soilhgt_data, istatus)
104 if (istatus == 0) then
106 if (trim(soilhgt_data%field) == 'SOILHGT ' .and. soilhgt_data%xlvl == 200100.) then
107 if (.not. associated(height_data%slab)) then
108 allocate(height_data%slab(soilhgt_data%nx,soilhgt_data%ny))
110 height_data = soilhgt_data
111 height_data%hdate = '0000-00-00_00:00:00 '
112 height_data%xfcst = 0.
113 height_data%field = 'HGT '
114 height_data%slab = 0.
116 !print *,'height_data%nx ,soilhgt_data%nx = ',height_data%nx ,soilhgt_data%nx
117 !print *,'height_data%ny ,soilhgt_data%ny = ',height_data%ny ,soilhgt_data%ny
119 if (height_data%nx /= soilhgt_data%nx .or. &
120 height_data%ny /= soilhgt_data%ny .or. &
121 height_data%iproj /= soilhgt_data%iproj) then
122 call mprintf(.true.,ERROR,'Mismatch in height field dimensions in file %s', &
123 s1=trim(input_name)//':'//temp_date(1:13))
127 file = 'util/vertical_grid_70_20m_80km.txt' , &
128 form = 'formatted' , &
129 access = 'sequential' , &
133 if ( istatus /= 0 ) then
134 call mprintf(.true.,ERROR,'Cannot open the UKMO file util/vertical_grid_70_20m_80km.txt')
140 read (10 , fmt='(30x,i2)' ) model_levels
141 read (10 , fmt='(30x,i2)' ) first_constant_r_rho_level
142 read (10 , fmt='(30x,f17.11)' ) z_top_of_model
143 print *,'model_levels, first_constant_r_rho_level, z_top_of_model = ', model_levels, first_constant_r_rho_level, z_top_of_model
147 allocate ( eta ( model_levels ) )
149 do k_loop = 1 , first_constant_r_rho_level-1
150 read ( 10 , fmt='(65x,f10.7)' ) eta(k_loop)
151 !print *,k_loop,' eta = ',eta(k_loop)
153 k_loop = first_constant_r_rho_level
154 read ( 10 , fmt='(29x,f10.7,26x,f10.7)' ) etac , eta(k_loop)
155 do k_loop = first_constant_r_rho_level+1 , model_levels
156 read ( 10 , fmt='(65x,f10.7)' ) eta(k_loop)
157 !print *,k_loop,' eta = ',eta(k_loop)
168 call read_met_close()
171 call mprintf(.true.,ERROR,'Problem opening %s at time %s', s1=input_name, s2=temp_date(1:13))
174 ! Now we have to write the height out for each time.
176 if (associated(height_data%slab)) then
178 still_more_dates_to_process = .true.
179 soilhgt_data%xfcst= 0.
180 soilhgt_data%hdate= output_date // '.0000'
181 height_data%xfcst= 0.
182 height_data%hdate= output_date // '.0000'
185 all_dates : do while ( still_more_dates_to_process )
187 print *,'Generating ',temp_count,' height levels for ',output_date,'.'
189 call write_met_init('HGT', .false., output_date(1:13), istatus)
190 soilhgt_data%xlvl = 200100
191 soilhgt_data%field = 'SOILHGT '
192 soilhgt_data%desc = 'Computed Geopotential Height, UKMO diagnostic '
194 ! Corrections for UKMO
196 ! soilhgt_data%deltalon= 360. / real(soilhgt_data%nx)
198 do j_loop = 1 , soilhgt_data%ny
199 do i_loop = 1 , soilhgt_data%nx
200 soilhgt_data%slab(i_loop,j_loop) = soil_hold(i_loop,j_loop)
204 call write_next_met_field(soilhgt_data, istatus)
206 height_data%version= soilhgt_data%version
207 height_data%nx= soilhgt_data%nx
208 height_data%ny= soilhgt_data%ny
209 height_data%iproj= soilhgt_data%iproj
210 ! height_data%xfcst= soilhgt_data%xfcst
211 ! height_data%xlvl= soilhgt_data%xlvl
212 height_data%startlat= soilhgt_data%startlat
213 height_data%startlon= soilhgt_data%startlon
214 height_data%starti= soilhgt_data%starti
215 height_data%startj= soilhgt_data%startj
216 height_data%deltalat= soilhgt_data%deltalat
217 height_data%deltalon= soilhgt_data%deltalon
218 height_data%dx= soilhgt_data%dx
219 height_data%dy= soilhgt_data%dy
220 height_data%xlonc= soilhgt_data%xlonc
221 height_data%truelat1= soilhgt_data%truelat1
222 height_data%truelat2= soilhgt_data%truelat2
223 height_data%earth_radius= soilhgt_data%earth_radius
224 height_data%is_wind_grid_rel= soilhgt_data%is_wind_grid_rel
225 height_data%field= 'HGT '
226 ! height_data%hdate= soilhgt_data%hdate
227 height_data%units= soilhgt_data%units
228 height_data%map_source= soilhgt_data%map_source
229 height_data%desc= soilhgt_data%desc
231 do k_loop = MIN(model_levels,temp_count) , first_constant_r_rho_level+1 , -1
232 ! height_data%xlvl = temp_count + 1 - k_loop
233 height_data%xlvl = k_loop
234 do j_loop = 1 , height_data%ny
235 do i_loop = 1 , height_data%nx
236 height_data%slab(i_loop,j_loop) = eta(k_loop) * z_top_of_model
240 call write_next_met_field(height_data, istatus)
243 do k_loop = first_constant_r_rho_level , 1 , -1
244 ! height_data%xlvl = temp_count + 1 - k_loop
245 height_data%xlvl = k_loop
246 do j_loop = 1 , height_data%ny
247 do i_loop = 1 , height_data%nx
248 height_data%slab(i_loop,j_loop) = eta(k_loop) * z_top_of_model + &
249 soil_hold(i_loop,j_loop) * ( 1. - eta(k_loop) / etac ) **2
253 call write_next_met_field(height_data, istatus)
256 call write_met_close()
258 call geth_newdate ( output_date , valid_date , interval_seconds * date_loop )
259 date_loop = date_loop + 1
261 if ( TRIM(output_date) > TRIM(end_date(1)) ) then
262 still_more_dates_to_process = .false.
270 call mprintf(.true.,STDOUT,' *** Successful completion of program height_ukmo.exe *** ')
274 end program height_ukmo