1 module interp_option_module
5 use misc_definitions_module
9 integer, parameter :: BUFSIZE=128
11 integer :: num_entries
12 integer, pointer, dimension(:) :: output_stagger
13 real, pointer, dimension(:) :: masked, fill_missing, missing_value, &
14 interp_mask_val, interp_land_mask_val, interp_water_mask_val
15 logical, pointer, dimension(:) :: output_this_field, is_u_field, is_v_field, is_derived_field, is_mandatory
16 character (len=128), pointer, dimension(:) :: fieldname, interp_method, v_interp_method, &
17 interp_mask, interp_land_mask, interp_water_mask, &
18 flag_in_output, output_name, from_input, z_dim_name, level_template, &
20 character (len=1), pointer, dimension(:) :: interp_mask_relational, interp_land_mask_relational, interp_water_mask_relational
21 type (list), pointer, dimension(:) :: fill_lev_list
22 type (list) :: flag_in_output_list
26 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27 ! Name: read_interp_table
30 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
31 subroutine read_interp_table()
34 integer :: i, p1, p2, idx, eos, ispace, funit, istatus, nparams, s1, s2
35 logical :: is_used, have_specification
36 character (len=128) :: lev_string, fill_string, flag_string, flag_val
37 character (len=BUFSIZE) :: buffer
40 inquire(unit=funit, opened=is_used)
41 if (.not. is_used) exit
47 open(funit, file=trim(opt_metgrid_tbl_path)//'METGRID.TBL', form='formatted', status='old', err=1001)
49 do while (istatus == 0)
50 read(funit, '(a)', iostat=istatus) buffer
51 if (istatus == 0) then
54 ! Is this line a comment?
55 if (buffer(1:1) == '#') then
57 ! Are we beginning a new field specification?
58 else if (index(buffer,'=====') /= 0) then
59 if (nparams > 0) num_entries = num_entries + 1
63 eos = index(buffer,'#')
64 if (eos /= 0) buffer(eos:BUFSIZE) = ' '
66 ! Does this line contain at least one parameter specification?
67 if (index(buffer,'=') /= 0) then
77 ! Allocate one extra array element to act as the default
78 ! BUG: Maybe this will not be necessary if we move to a module with query routines for
79 ! parsing the METGRID.TBL
80 num_entries = num_entries + 1
82 allocate(fieldname(num_entries))
83 allocate(mpas_name(num_entries))
84 allocate(interp_method(num_entries))
85 allocate(v_interp_method(num_entries))
86 allocate(masked(num_entries))
87 allocate(fill_missing(num_entries))
88 allocate(missing_value(num_entries))
89 allocate(fill_lev_list(num_entries))
90 allocate(interp_mask(num_entries))
91 allocate(interp_land_mask(num_entries))
92 allocate(interp_water_mask(num_entries))
93 allocate(interp_mask_val(num_entries))
94 allocate(interp_land_mask_val(num_entries))
95 allocate(interp_water_mask_val(num_entries))
96 allocate(interp_mask_relational(num_entries))
97 allocate(interp_land_mask_relational(num_entries))
98 allocate(interp_water_mask_relational(num_entries))
99 allocate(level_template(num_entries))
100 allocate(flag_in_output(num_entries))
101 allocate(output_name(num_entries))
102 allocate(from_input(num_entries))
103 allocate(z_dim_name(num_entries))
104 allocate(output_stagger(num_entries))
105 allocate(output_this_field(num_entries))
106 allocate(is_u_field(num_entries))
107 allocate(is_v_field(num_entries))
108 allocate(is_derived_field(num_entries))
109 allocate(is_mandatory(num_entries))
117 flag_in_output(i) = ' '
120 z_dim_name(i) = 'num_metgrid_levels'
121 interp_method(i) = 'nearest_neighbor'
122 v_interp_method(i) = 'linear_log_p'
123 masked(i) = NOT_MASKED
124 fill_missing(i) = NAN
125 missing_value(i) = NAN
126 call list_init(fill_lev_list(i))
128 interp_land_mask(i) = ' '
129 interp_water_mask(i) = ' '
130 interp_mask_val(i) = NAN
131 interp_land_mask_val(i) = NAN
132 interp_water_mask_val(i) = NAN
133 interp_mask_relational(i) = ' '
134 interp_land_mask_relational(i) = ' '
135 interp_water_mask_relational(i) = ' '
136 level_template(i) = ' '
137 if (gridtype == 'C') then
138 output_stagger(i) = M
139 else if (gridtype == 'E') then
140 output_stagger(i) = HH
142 output_this_field(i) = .true.
143 is_u_field(i) = .false.
144 is_v_field(i) = .false.
145 is_derived_field(i) = .false.
146 is_mandatory(i) = .false.
148 call list_init(flag_in_output_list)
154 do while (istatus == 0)
156 read(funit, '(a)', iostat=istatus) buffer
157 if (istatus == 0) then
160 ! Is this line a comment?
161 if (buffer(1:1) == '#') then
164 ! Are we beginning a new field specification?
165 else if (index(buffer,'=====') /= 0) then !{
166 if (nparams > 0) i = i + 1
170 ! Check whether the current line is a comment
171 if (buffer(1:1) /= '#') then
172 have_specification = .true.
174 have_specification = .false.
177 ! If only part of the line is a comment, just turn the comment into spaces
178 eos = index(buffer,'#')
179 if (eos /= 0) buffer(eos:BUFSIZE) = ' '
181 do while (have_specification) !{
183 ! If this line has no semicolon, it may contain a single specification,
184 ! so we set have_specification = .false. to prevent the line from being
185 ! processed again and "pretend" that the last character was a semicolon
186 eos = index(buffer,';')
188 have_specification = .false.
192 idx = index(buffer(1:eos-1),'=')
194 if (idx /= 0) then !{
195 nparams = nparams + 1
197 if (index('name',trim(buffer(1:idx-1))) /= 0 .and. &
198 len_trim('name') == len_trim(buffer(1:idx-1))) then
200 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
204 fieldname(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
206 else if (index('mpas_name',trim(buffer(1:idx-1))) /= 0 .and. &
207 len_trim('mpas_name') == len_trim(buffer(1:idx-1))) then
209 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
213 mpas_name(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
215 else if (index('from_input',trim(buffer(1:idx-1))) /= 0 .and. &
216 len_trim('from_input') == len_trim(buffer(1:idx-1))) then
218 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
222 from_input(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
224 else if (index('z_dim_name',trim(buffer(1:idx-1))) /= 0 .and. &
225 len_trim('z_dim_name') == len_trim(buffer(1:idx-1))) then
227 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
231 z_dim_name(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
233 else if (index('output_stagger',trim(buffer(1:idx-1))) /= 0 .and. &
234 len_trim('output_stagger') == len_trim(buffer(1:idx-1))) then
235 if (index('M',trim(buffer(idx+1:eos-1))) /= 0) then
236 output_stagger(i) = M
237 else if (index('U',trim(buffer(idx+1:eos-1))) /= 0) then
238 output_stagger(i) = U
239 else if (index('V',trim(buffer(idx+1:eos-1))) /= 0) then
240 output_stagger(i) = V
241 else if (index('HH',trim(buffer(idx+1:eos-1))) /= 0) then
242 output_stagger(i) = HH
243 else if (index('VV',trim(buffer(idx+1:eos-1))) /= 0) then
244 output_stagger(i) = VV
247 else if (index('output',trim(buffer(1:idx-1))) /= 0 .and. &
248 len_trim('output') == len_trim(buffer(1:idx-1))) then
249 if (index('yes',trim(buffer(idx+1:eos-1))) /= 0) then
250 output_this_field(i) = .true.
251 else if (index('no',trim(buffer(idx+1:eos-1))) /= 0) then
252 output_this_field(i) = .false.
255 else if (index('is_u_field',trim(buffer(1:idx-1))) /= 0 .and. &
256 len_trim('is_u_field') == len_trim(buffer(1:idx-1))) then
257 if (index('yes',trim(buffer(idx+1:eos-1))) /= 0) then
258 is_u_field(i) = .true.
259 else if (index('no',trim(buffer(idx+1:eos-1))) /= 0) then
260 is_u_field(i) = .false.
263 else if (index('is_v_field',trim(buffer(1:idx-1))) /= 0 .and. &
264 len_trim('is_v_field') == len_trim(buffer(1:idx-1))) then
265 if (index('yes',trim(buffer(idx+1:eos-1))) /= 0) then
266 is_v_field(i) = .true.
267 else if (index('no',trim(buffer(idx+1:eos-1))) /= 0) then
268 is_v_field(i) = .false.
271 else if (index('derived',trim(buffer(1:idx-1))) /= 0 .and. &
272 len_trim('derived') == len_trim(buffer(1:idx-1))) then
273 if (index('yes',trim(buffer(idx+1:eos-1))) /= 0) then
274 is_derived_field(i) = .true.
275 else if (index('no',trim(buffer(idx+1:eos-1))) /= 0) then
276 is_derived_field(i) = .false.
279 else if (index('mandatory',trim(buffer(1:idx-1))) /= 0 .and. &
280 len_trim('mandatory') == len_trim(buffer(1:idx-1))) then
281 if (index('yes',trim(buffer(idx+1:eos-1))) /= 0) then
282 is_mandatory(i) = .true.
283 else if (index('no',trim(buffer(idx+1:eos-1))) /= 0) then
284 is_mandatory(i) = .false.
287 else if (index('interp_option',trim(buffer(1:idx-1))) /= 0 .and. &
288 len_trim('interp_option') == len_trim(buffer(1:idx-1))) then
290 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
293 interp_method(i) = ' '
294 interp_method(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
296 else if (index('vertical_interp_option',trim(buffer(1:idx-1))) /= 0 .and. &
297 len_trim('vertical_interp_option') == len_trim(buffer(1:idx-1))) then
299 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
302 v_interp_method(i) = ' '
303 v_interp_method(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
305 else if (index('level_template',trim(buffer(1:idx-1))) /= 0 .and. &
306 len_trim('level_template') == len_trim(buffer(1:idx-1))) then
308 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
311 level_template(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
313 else if (index('interp_mask',trim(buffer(1:idx-1))) /= 0 .and. &
314 len_trim('interp_mask') == len_trim(buffer(1:idx-1))) then
316 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
319 p1 = index(buffer(idx+1:ispace-1),'(')
320 p2 = index(buffer(idx+1:ispace-1),')')
321 s1 = index(buffer(idx+1:ispace-1),'<')
322 s2 = index(buffer(idx+1:ispace-1),'>')
323 if (p1 == 0 .or. p2 == 0) then
324 call mprintf(.true.,WARN, &
325 'Problem in specifying interp_mask flag. Setting masked flag to 0.')
327 interp_mask(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
328 interp_mask_val(i) = 0
330 ! Parenthesis found; additionally, there may be a relational symbol
331 if ((s1 /= 0) .OR. (s2 /= 0)) then
333 interp_mask_relational(i) = buffer(idx+s1:idx+s1)
334 else if (s2 > 0) then
335 interp_mask_relational(i) = buffer(idx+s2:idx+s2)
338 interp_mask(i)(1:p1) = buffer(idx+1:idx+p1-1)
339 read(buffer(idx+p1+2:idx+p2-1),*,err=1000) interp_mask_val(i)
341 ! No relational symbol
343 interp_mask(i)(1:p1) = buffer(idx+1:idx+p1-1)
344 read(buffer(idx+p1+1:idx+p2-1),*,err=1000) interp_mask_val(i)
348 else if (index('interp_land_mask',trim(buffer(1:idx-1))) /= 0 .and. &
349 len_trim('interp_land_mask') == len_trim(buffer(1:idx-1))) then
351 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
354 p1 = index(buffer(idx+1:ispace-1),'(')
355 p2 = index(buffer(idx+1:ispace-1),')')
356 s1 = index(buffer(idx+1:ispace-1),'<')
357 s2 = index(buffer(idx+1:ispace-1),'>')
358 if (p1 == 0 .or. p2 == 0) then
359 call mprintf(.true.,WARN, &
360 'Problem in specifying interp_land_mask flag. Setting masked flag to 0.')
361 interp_land_mask(i) = ' '
362 interp_land_mask(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
363 interp_land_mask_val(i) = 0
365 ! Parenthesis found; additionally, there may be a relational symbol
366 if ((s1 /= 0) .OR. (s2 /= 0)) then
368 interp_land_mask_relational(i) = buffer(idx+s1:idx+s1)
369 else if (s2 > 0) then
370 interp_land_mask_relational(i) = buffer(idx+s2:idx+s2)
372 interp_land_mask(i) = ' '
373 interp_land_mask(i)(1:p1) = buffer(idx+1:idx+p1-1)
374 read(buffer(idx+p1+2:idx+p2-1),*,err=1000) interp_land_mask_val(i)
376 ! No relational symbol
377 interp_land_mask(i) = ' '
378 interp_land_mask(i)(1:p1) = buffer(idx+1:idx+p1-1)
379 read(buffer(idx+p1+1:idx+p2-1),*,err=1000) interp_land_mask_val(i)
383 else if (index('interp_water_mask',trim(buffer(1:idx-1))) /= 0 .and. &
384 len_trim('interp_water_mask') == len_trim(buffer(1:idx-1))) then
386 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
389 p1 = index(buffer(idx+1:ispace-1),'(')
390 p2 = index(buffer(idx+1:ispace-1),')')
391 s1 = index(buffer(idx+1:ispace-1),'<')
392 s2 = index(buffer(idx+1:ispace-1),'>')
393 if (p1 == 0 .or. p2 == 0) then
394 call mprintf(.true.,WARN, &
395 'Problem in specifying interp_water_mask flag. Setting masked flag to 0.')
396 interp_water_mask(i) = ' '
397 interp_water_mask(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
398 interp_water_mask_val(i) = 0
400 ! Parenthesis found; additionally, there may be a relational symbol
401 if ((s1 /= 0) .OR. (s2 /= 0)) then
403 interp_water_mask_relational(i) = buffer(idx+s1:idx+s1)
404 else if (s2 > 0) then
405 interp_water_mask_relational(i) = buffer(idx+s2:idx+s2)
407 interp_water_mask(i) = ' '
408 interp_water_mask(i)(1:p1) = buffer(idx+1:idx+p1-1)
409 read(buffer(idx+p1+2:idx+p2-1),*,err=1000) interp_water_mask_val(i)
411 ! No relational symbol
412 interp_water_mask(i) = ' '
413 interp_water_mask(i)(1:p1) = buffer(idx+1:idx+p1-1)
414 read(buffer(idx+p1+1:idx+p2-1),*,err=1000) interp_water_mask_val(i)
418 else if (index('masked',trim(buffer(1:idx-1))) /= 0 .and. &
419 len_trim('masked') == len_trim(buffer(1:idx-1))) then
420 if (index('water',trim(buffer(idx+1:eos-1))) /= 0) then
421 masked(i) = MASKED_WATER
422 else if (index('land',trim(buffer(idx+1:eos-1))) /= 0) then
423 masked(i) = MASKED_LAND
424 else if (index('both',trim(buffer(idx+1:eos-1))) /= 0) then
425 masked(i) = MASKED_BOTH
428 else if (index('flag_in_output',trim(buffer(1:idx-1))) /= 0 .and. &
429 len_trim('flag_in_output') == len_trim(buffer(1:idx-1))) then
431 flag_string(1:eos-idx-1) = buffer(idx+1:eos-1)
432 if (list_search(flag_in_output_list, ckey=flag_string, cvalue=flag_val)) then
433 call mprintf(.true.,WARN, 'In METGRID.TBL, %s is given as a flag more than once.', &
435 flag_in_output(i)(1:eos-idx-1) = buffer(idx+1:eos-1)
437 flag_in_output(i)(1:eos-idx-1) = buffer(idx+1:eos-1)
438 write(flag_val,'(i1)') 1
439 call list_insert(flag_in_output_list, ckey=flag_string, cvalue=flag_val)
442 else if (index('output_name',trim(buffer(1:idx-1))) /= 0 .and. &
443 len_trim('output_name') == len_trim(buffer(1:idx-1))) then
445 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
449 output_name(i)(1:ispace-idx) = buffer(idx+1:ispace-1)
451 else if (index('fill_missing',trim(buffer(1:idx-1))) /= 0 .and. &
452 len_trim('fill_missing') == len_trim(buffer(1:idx-1))) then
453 read(buffer(idx+1:eos-1),*) fill_missing(i)
455 else if (index('missing_value',trim(buffer(1:idx-1))) /= 0 .and. &
456 len_trim('missing_value') == len_trim(buffer(1:idx-1))) then
457 read(buffer(idx+1:eos-1),*) missing_value(i)
459 else if (index('fill_lev',trim(buffer(1:idx-1))) /= 0 .and. &
460 len_trim('fill_lev') == len_trim(buffer(1:idx-1))) then
462 do while ((ispace < eos) .and. (buffer(ispace:ispace) /= ' '))
466 fill_string(1:ispace-idx-1) = buffer(idx+1:ispace-1)
467 ispace = index(fill_string,':')
468 if (ispace /= 0) then
469 write(lev_string,'(a)') fill_string(1:ispace-1)
471 write(lev_string,'(a)') 'all'
473 write(fill_string,'(a)') trim(fill_string(ispace+1:128))
474 fill_string(128-ispace:128) = ' '
475 call list_insert(fill_lev_list(i), ckey=lev_string, cvalue=fill_string)
478 call mprintf(.true.,WARN, 'In METGRID.TBL, unrecognized option %s in entry %i.', s1=buffer(1:idx-1), i1=idx)
481 end if !} index(buffer(1:eos-1),'=') /= 0
483 ! BUG: If buffer has non-whitespace characters but no =, then maybe a wrong specification?
485 buffer = buffer(eos+1:BUFSIZE)
486 end do ! while eos /= 0 }
488 end if !} index(buffer, '=====') /= 0
493 call check_table_specs()
499 1000 call mprintf(.true.,ERROR,'The mask value of the interp_mask specification must '// &
500 'be a real value, enclosed in parentheses immediately after the field name.')
502 1001 call mprintf(.true.,ERROR,'Could not open file METGRID.TBL')
503 1002 call mprintf(.true.,ERROR,'Symbol expected < >. Check METGRID.TBL for missing symbol or erroreous entry')
505 end subroutine read_interp_table
508 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
509 ! Name: check_table_specs
511 ! Pupose: Perform basic consistency and sanity checks on the METGRID.TBL
512 ! entries supplied by the user.
513 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
514 subroutine check_table_specs()
523 ! For C grid, U field must be on U staggering, and V field must be on
524 ! V staggering; for E grid, U and V must be on VV staggering.
525 if (gridtype == 'C') then
526 if (is_u_field(i) .and. output_stagger(i) /= U) then
527 call mprintf(.true.,ERROR,'In entry %i of METGRID.TBL, the wind U-component field '// &
528 'must be interpolated to the U staggered grid points.',i1=i)
529 else if (is_v_field(i) .and. output_stagger(i) /= V) then
530 call mprintf(.true.,ERROR,'In entry %i of METGRID.TBL, the wind V-component field '// &
531 'must be interpolated to the V staggered grid points.',i1=i)
534 if (output_stagger(i) == VV) then
535 call mprintf(.true.,ERROR,'In entry %i of METGRID.TBL, VV is not a valid output staggering for ARW.',i1=i)
536 else if (output_stagger(i) == HH) then
537 call mprintf(.true.,ERROR,'In entry %i of METGRID.TBL, HH is not a valid output staggering for ARW.',i1=i)
540 if (masked(i) /= NOT_MASKED .and. output_stagger(i) /= M) then
541 call mprintf(.true.,ERROR,'In entry %i of METGRID.TBL, staggered output field '// &
542 'cannot use the ''masked'' option.',i1=i)
545 else if (gridtype == 'E') then
546 if (is_u_field(i) .and. output_stagger(i) /= VV) then
547 call mprintf(.true.,ERROR,'In entry %i of METGRID.TBL, the wind U-component field '// &
548 'must be interpolated to the V staggered grid points.',i1=i)
549 else if (is_v_field(i) .and. output_stagger(i) /= VV) then
550 call mprintf(.true.,ERROR,'In entry %i of METGRID.TBL, the wind V-component field '// &
551 'must be interpolated to the V staggered grid points.',i1=i)
554 if (output_stagger(i) == M) then
555 call mprintf(.true.,ERROR,'In entry %i of METGRID.TBL, M is not a valid output staggering for NMM.',i1=i)
556 else if (output_stagger(i) == U) then
557 call mprintf(.true.,ERROR,'In entry %i of METGRID.TBL, U is not a valid output staggering for NMM.',i1=i)
558 else if (output_stagger(i) == V) then
559 call mprintf(.true.,ERROR,'In entry %i of METGRID.TBL, V is not a valid output staggering for NMM.',i1=i)
562 if (masked(i) /= NOT_MASKED .and. output_stagger(i) /= HH) then
563 call mprintf(.true.,ERROR,'In entry %i of METGRID.TBL, staggered output field '// &
564 'cannot use the ''masked'' option.',i1=i)
570 end subroutine check_table_specs
573 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
574 ! Name: get_z_dim_name
577 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
578 subroutine get_z_dim_name(fldname, zdim_name)
583 character (len=*), intent(in) :: fldname
584 character (len=32), intent(out) :: zdim_name
589 zdim_name = z_dim_name(num_entries)(1:32)
591 if (trim(fldname) == trim(fieldname(i))) then
592 zdim_name = z_dim_name(i)(1:32)
597 end subroutine get_z_dim_name
600 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
601 ! Name: mpas_name_to_idx
604 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
605 function mpas_name_to_idx(mpasname) result(idx)
610 character (len=*), intent(in) :: mpasname
620 if (trim(mpasname) == trim(mpas_name(i))) then
626 end function mpas_name_to_idx
629 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
630 ! Name: mpas_to_intermediate_name
633 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
634 function mpas_to_intermediate_name(mpasname) result(intermediate_name)
639 character (len=*), intent(in) :: mpasname
642 character (len=128) :: intermediate_name
647 intermediate_name = fieldname(num_entries)
649 if (trim(mpasname) == trim(mpas_name(i))) then
650 intermediate_name = fieldname(i)
655 end function mpas_to_intermediate_name
658 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
659 ! Name: mpas_output_stagger
662 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
663 function mpas_output_stagger(mpasname) result(istagger)
668 character (len=*), intent(in) :: mpasname
678 if (trim(mpasname) == trim(mpas_name(i))) then
679 istagger = output_stagger(i)
684 end function mpas_output_stagger
687 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
688 ! Name: get_gcell_threshold
691 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
692 subroutine get_gcell_threshold(interp_opt, threshold, istatus)
697 integer, intent(out) :: istatus
698 real, intent(out) :: threshold
699 character (len=128), intent(in) :: interp_opt
707 i = index(interp_opt,'average_gcell')
710 ! Check for a threshold
711 p1 = index(interp_opt(i:128),'(')
712 p2 = index(interp_opt(i:128),')')
713 if (p1 /= 0 .and. p2 /= 0) then
714 read(interp_opt(p1+1:p2-1),*,err=1000) threshold
716 call mprintf(.true.,WARN, 'Problem in specifying threshold for average_gcell interp option. Setting threshold to 1.0')
724 1000 call mprintf(.true.,ERROR, &
725 'Threshold option to average_gcell interpolator must be a real number, '// &
726 'enclosed in parentheses immediately after keyword "average_gcell"')
728 end subroutine get_gcell_threshold
731 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
732 ! Name: get_constant_fill_lev
735 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
736 subroutine get_constant_fill_lev(fill_opt, fill_const, istatus)
741 integer, intent(out) :: istatus
742 real, intent(out) :: fill_const
743 character (len=128), intent(in) :: fill_opt
751 i = index(fill_opt,'const')
754 ! Check for a threshold
755 p1 = index(fill_opt(i:128),'(')
756 p2 = index(fill_opt(i:128),')')
757 if (p1 /= 0 .and. p2 /= 0) then
758 read(fill_opt(p1+1:p2-1),*,err=1000) fill_const
760 call mprintf(.true.,WARN, 'Problem in specifying fill_lev constant. Setting fill_const to %f', f1=NAN)
768 1000 call mprintf(.true.,ERROR, &
769 'Constant option to fill_lev must be a real number, enclosed in parentheses '// &
770 'immediately after keyword "const"')
772 end subroutine get_constant_fill_lev
775 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
776 ! Name: get_fill_src_level
779 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
780 subroutine get_fill_src_level(fill_opt, fill_src, fill_src_level)
785 integer, intent(out) :: fill_src_level
786 character (len=128), intent(in) :: fill_opt
787 character (len=128), intent(out) :: fill_src
792 ! Check for a level in parentheses
793 p1 = index(fill_opt,'(')
794 p2 = index(fill_opt,')')
795 if (p1 /= 0 .and. p2 /= 0) then
796 read(fill_opt(p1+1:p2-1),*,err=1000) fill_src_level
798 write(fill_src,'(a)') fill_opt(1:p1-1)
806 1000 call mprintf(.true.,ERROR, &
807 'For fill_lev specification, level in source field must be an integer, '// &
808 'enclosed in parentheses immediately after the fieldname')
810 end subroutine get_fill_src_level
813 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
814 ! Name: interp_option_destroy
817 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
818 subroutine interp_option_destroy()
825 deallocate(fieldname)
826 deallocate(from_input)
827 deallocate(z_dim_name)
828 deallocate(interp_method)
829 deallocate(v_interp_method)
831 deallocate(fill_missing)
832 deallocate(missing_value)
834 call list_destroy(fill_lev_list(i))
836 deallocate(fill_lev_list)
837 deallocate(interp_mask)
838 deallocate(interp_land_mask)
839 deallocate(interp_water_mask)
840 deallocate(interp_mask_val)
841 deallocate(interp_land_mask_val)
842 deallocate(interp_water_mask_val)
843 deallocate(interp_mask_relational)
844 deallocate(interp_land_mask_relational)
845 deallocate(interp_water_mask_relational)
846 deallocate(level_template)
847 deallocate(flag_in_output)
848 deallocate(output_name)
849 deallocate(output_stagger)
850 deallocate(output_this_field)
851 deallocate(is_u_field)
852 deallocate(is_v_field)
853 deallocate(is_derived_field)
854 deallocate(is_mandatory)
855 call list_destroy(flag_in_output_list)
857 end subroutine interp_option_destroy
859 end module interp_option_module