10 use fckit_configuration_module,
only: fckit_configuration
43 REAL(kind_real),
PARAMETER :: &
44 &rdgas = 2.8704e+2_kind_real,&
45 &rvgas = 4.6150e+2_kind_real,&
46 &rv_rd = rvgas/rdgas,&
48 &zvir = rv_rd - 1_kind_real,&
49 &tice = 273.16_kind_real,&
50 &grav = 9.81_kind_real,&
51 &aerosol_concentration_minvalue=1.e-16_kind_real,&
52 &aerosol_concentration_minvalue_layer=tiny(rdgas),&
53 &ozone_default_value=1.e-3_kind_real
60 integer :: n_absorbers
64 character(len=MAXVARLEN),
allocatable :: absorbers(:)
65 integer,
allocatable :: absorber_id(:)
66 integer,
allocatable :: absorber_units(:)
67 character(len=MAXVARLEN),
allocatable :: clouds(:,:)
68 integer,
allocatable :: cloud_id(:)
69 character(len=MAXVARLEN),
allocatable :: surfaces(:)
71 character(len=255),
allocatable :: sensor_id(:)
72 character(len=255) :: endian_type
73 character(len=255) :: coefficient_path
74 character(len=255) :: &
75 irwatercoeff_file, irlandcoeff_file, irsnowcoeff_file, iricecoeff_file, &
76 viswatercoeff_file, vislandcoeff_file, vissnowcoeff_file, visicecoeff_file, &
78 integer,
allocatable :: land_wsi(:)
79 real(kind_real) :: cloud_fraction = -1.0_kind_real
81 character(len=MAXVARLEN) :: aerosol_option
82 character(len=255) :: salinity_option
83 character(len=MAXVARLEN) :: sfc_wind_geovars
103 character(len=MAXVARLEN),
parameter :: &
108 character(len=MAXVARLEN),
parameter :: &
110 absorber_id_name(1:n_valid_absorber_ids)
111 integer,
parameter :: &
113 [ h2o_id, co2_id, o3_id, n2o_id, &
114 co_id, ch4_id, o2_id, no_id, &
115 so2_id, no2_id, nh3_id, hno3_id, &
116 oh_id, hf_id, hcl_id, hbr_id, &
117 hi_id, clo_id, ocs_id, h2co_id, &
118 hocl_id, n2_id, hcn_id, ch3l_id, &
119 h2o2_id, c2h2_id, c2h6_id, ph3_id, &
120 cof2_id, sf6_id, h2s_id,hcooh_id ]
121 integer,
parameter :: &
123 mass_mixing_ratio_units &
124 , volume_mixing_ratio_units &
125 , volume_mixing_ratio_units &
128 character(len=MAXVARLEN),
parameter :: &
133 , [n_valid_cloud_categories,2] )
136 character(len=MAXVARLEN),
parameter :: &
138 cloud_category_name(1:n_valid_cloud_categories)
139 integer,
parameter :: &
150 character(len=MAXVARLEN),
parameter :: &
154 character(len=MAXVARLEN),
parameter :: &
156 [ character(len=
maxvarlen)::
'Water_Temperature',
'Wind_Speed',
'Wind_Direction',
'Salinity' ]
158 character(len=MAXVARLEN),
parameter :: &
169 type(fckit_configuration),
intent(in) :: f_confopts
170 type(fckit_configuration),
intent(in) :: f_confoper
172 character(*),
PARAMETER :: routine_name =
'crtm_conf_setup'
173 character(len=255) :: irwatercoeff, viswatercoeff, &
174 irvislandcoeff, irvissnowcoeff, irvisicecoeff, &
176 integer :: jspec, ivar
177 character(len=max_string) :: message
178 character(len=:),
allocatable :: str
179 character(len=:),
allocatable :: str_array(:)
181 CHARACTER(len=MAXVARLEN),
ALLOCATABLE :: var_aerosols(:)
196 if (f_confoper%has(
"Absorbers")) &
197 conf%n_Absorbers = conf%n_Absorbers + f_confoper%get_size(
"Absorbers")
199 allocate( conf%Absorbers ( conf%n_Absorbers ), &
200 conf%Absorber_Id ( conf%n_Absorbers ), &
201 conf%Absorber_Units( conf%n_Absorbers ) )
203 if (conf%n_Absorbers > 0)
then
204 call f_confoper%get_or_die(
"Absorbers",str_array)
205 conf%Absorbers(1:conf%n_Absorbers) = str_array
209 do jspec = 2, conf%n_Absorbers
210 if ( any(conf%Absorbers(jspec-1) == conf%Absorbers(jspec:conf%n_Absorbers)) )
then
211 write(message,*) trim(routine_name),
' error: ',trim(conf%Absorbers(jspec)),
' is duplicated in Absorbers'
212 call abor1_ftn(message)
217 do jspec = 1, conf%n_Absorbers
220 write(message,*) trim(routine_name),
' error: ',trim(conf%Absorbers(jspec)),
' not supported by UFO_Absorbers'
221 call abor1_ftn(message)
232 if (f_confoper%has(
"Clouds")) &
233 conf%n_Clouds = f_confoper%get_size(
"Clouds")
234 allocate( conf%Clouds ( conf%n_Clouds,2), &
235 conf%Cloud_Id( conf%n_Clouds ) )
236 if (conf%n_Clouds > 0)
then
237 call f_confoper%get_or_die(
"Clouds",str_array)
238 conf%Clouds(1:conf%n_Clouds,1) = str_array
240 if (f_confoper%has(
"Cloud_Fraction"))
then
241 call f_confoper%get_or_die(
"Cloud_Fraction",conf%Cloud_Fraction)
242 if ( conf%Cloud_Fraction < 0.0 .or. &
243 conf%Cloud_Fraction > 1.0 )
then
244 write(message,*) trim(routine_name),
' error: must specify ' // &
245 ' 0.0 <= Cloud_Fraction <= 1.0' // &
246 ' or remove Cloud_Fraction from conf' // &
247 ' and provide as a geoval'
248 call abor1_ftn(message)
251 message = trim(routine_name) // &
252 ': Cloud_Fraction is not provided in conf.' // &
253 ' Will request as a geoval.'
254 CALL display_message(routine_name, trim(message), warning )
259 do jspec = 2, conf%n_Clouds
260 if ( any(conf%Clouds(jspec-1,1) == conf%Clouds(jspec:conf%n_Clouds,1)) )
then
261 write(message,*) trim(routine_name),
' error: ',trim(conf%Clouds(jspec,1)), &
262 ' is duplicated in Clouds'
263 call abor1_ftn(message)
268 do jspec = 1, conf%n_Clouds
270 if (ivar < 1 .or. ivar >
size(
ufo_clouds))
then
271 write(message,*) trim(routine_name),
' error: ',trim(conf%Clouds(jspec,1)),
' not supported by UFO_Clouds'
272 call abor1_ftn(message)
280 IF (f_confopts%has(
"AerosolOption"))
THEN
281 call f_confopts%get_or_die(
"AerosolOption",str)
282 conf%aerosol_option = str
283 conf%aerosol_option =
upper2lower(conf%aerosol_option)
285 conf%n_Aerosols=
SIZE(var_aerosols)
288 conf%aerosol_option =
""
294 if (f_confoper%has(
"Surfaces")) &
295 conf%n_Surfaces = conf%n_Surfaces + f_confoper%get_size(
"Surfaces")
297 allocate( conf%Surfaces ( conf%n_Surfaces ))
299 if (conf%n_Surfaces > 0)
then
300 call f_confoper%get_or_die(
"Surfaces",str_array)
301 conf%Surfaces(1:conf%n_Surfaces) = str_array
305 do jspec = 2, conf%n_Surfaces
306 if ( any(conf%Surfaces(jspec-1) == conf%Surfaces(jspec:conf%n_Surfaces)) )
then
307 write(message,*)
'crtm_conf_setup error: ',trim(conf%Surfaces(jspec)),
' is duplicated in Surfaces'
308 call abor1_ftn(message)
313 do jspec = 1, conf%n_Surfaces
316 write(message,*)
'crtm_conf_setup error: ',trim(conf%Surfaces(jspec)),
' not supported by UFO_Surfaces'
317 call abor1_ftn(message)
325 if (f_confoper%get(
'SurfaceWindGeoVars', str))
then
326 conf%sfc_wind_geovars = str
328 conf%sfc_wind_geovars =
'vector'
331 write(message,*)
'crtm_conf_setup error: invalid SurfaceWindGeoVars ',trim(str)
332 call abor1_ftn(message)
337 IF (f_confopts%get(
"Salinity",str))
THEN
338 conf%salinity_option = str
340 conf%salinity_option =
'off'
344 allocate(conf%SENSOR_ID(conf%n_Sensors))
347 call f_confopts%get_or_die(
"Sensor_ID",str)
348 conf%SENSOR_ID(conf%n_Sensors) = str
351 call f_confopts%get_or_die(
"EndianType",str)
352 conf%ENDIAN_TYPE = str
355 call f_confopts%get_or_die(
"CoefficientPath",str)
356 conf%COEFFICIENT_PATH = str
359 irwatercoeff =
"Nalli"
360 if (f_confopts%has(
"IRwaterCoeff"))
then
361 call f_confopts%get_or_die(
"IRwaterCoeff",str)
364 viswatercoeff =
"NPOESS"
365 if (f_confopts%has(
"VISwaterCoeff"))
then
366 call f_confopts%get_or_die(
"VISwaterCoeff",str)
369 irvislandcoeff =
"NPOESS"
370 if (f_confopts%has(
"IRVISlandCoeff"))
then
371 call f_confopts%get_or_die(
"IRVISlandCoeff",str)
374 irvissnowcoeff =
"NPOESS"
375 if (f_confopts%has(
"IRVISsnowCoeff"))
then
376 call f_confopts%get_or_die(
"IRVISsnowCoeff",str)
379 irvisicecoeff =
"NPOESS"
380 if (f_confopts%has(
"IRVISiceCoeff"))
then
381 call f_confopts%get_or_die(
"IRVISiceCoeff",str)
384 mwwatercoeff =
"FASTEM6"
385 if (f_confopts%has(
"MWwaterCoeff"))
then
386 call f_confopts%get_or_die(
"MWwaterCoeff",str)
391 select case (trim(irvislandcoeff))
393 allocate(conf%Land_WSI(2))
394 conf%Land_WSI(1:2) = (/16,24/)
396 allocate(conf%Land_WSI(2))
397 conf%Land_WSI(1:2) = (/15,17/)
399 allocate(conf%Land_WSI(1))
400 conf%Land_WSI(1) = -1
404 conf%IRwaterCoeff_File = trim(irwatercoeff)//
".IRwater.EmisCoeff.bin"
405 conf%IRlandCoeff_File = trim(irvislandcoeff)//
".IRland.EmisCoeff.bin"
406 conf%IRsnowCoeff_File = trim(irvissnowcoeff)//
".IRsnow.EmisCoeff.bin"
407 conf%IRiceCoeff_File = trim(irvisicecoeff)//
".IRice.EmisCoeff.bin"
410 conf%VISwaterCoeff_File = trim(viswatercoeff)//
".VISwater.EmisCoeff.bin"
411 conf%VISlandCoeff_File = trim(irvislandcoeff)//
".VISland.EmisCoeff.bin"
412 conf%VISsnowCoeff_File = trim(irvissnowcoeff)//
".VISsnow.EmisCoeff.bin"
413 conf%VISiceCoeff_File = trim(irvisicecoeff)//
".VISice.EmisCoeff.bin"
416 conf%MWwaterCoeff_File = trim(mwwatercoeff)//
".MWwater.EmisCoeff.bin"
419 if (f_confopts%has(
"InspectProfileNumber"))
then
420 call f_confopts%get_or_die(
"InspectProfileNumber",conf%inspect)
432 deallocate(conf%SENSOR_ID)
433 deallocate(conf%Land_WSI)
434 deallocate(conf%Absorbers)
435 deallocate(conf%Absorber_Id)
436 deallocate(conf%Absorber_Units)
437 deallocate(conf%Clouds)
438 deallocate(conf%Cloud_Id)
445 use fckit_mpi_module,
only: fckit_mpi_comm
449 integer,
intent(in) :: stat
450 character(*),
intent(in) :: program_name
451 character(*),
intent(in) :: message
452 type(fckit_mpi_comm),
intent(in) :: f_comm
454 character(max_string) :: rank_message
456 if ( stat /= success )
THEN
457 write(rank_message,*) trim(message),
" on rank ",f_comm%rank()
458 call display_message( program_name, rank_message, failure )
459 call abor1_ftn(
"Abort from "//program_name)
472 use missing_values_mod
475 integer,
intent(in) :: n_profiles, n_channels
476 type(c_ptr),
value,
intent(in) :: obss
477 integer(c_int),
intent(in) :: channels(:)
478 logical,
intent(inout) :: skip_profiles(:)
480 integer :: jprofile, jchannel
481 character(len=MAXVARLEN) :: varname
482 real(kind_real) :: obsval(n_profiles,n_channels)
486 real(c_double) :: missing
489 missing = missing_value(missing)
495 do jchannel = 1, n_channels
497 call obsspace_get_db(obss,
"ObsValue", varname, obsval(:,jchannel))
503 do jprofile = 1, n_profiles
504 skip_profiles(jprofile) = all(obsval(jprofile,:) == missing)
516 integer,
intent(in) :: n_profiles, n_layers
518 type(crtm_atmosphere_type),
intent(inout) :: atm(:)
524 character(max_string) :: err_msg
531 if (geoval%nval /= n_layers)
then
532 write(err_msg,*)
'Load_Atm_Data error: layers inconsistent!'
533 call abor1_ftn(err_msg)
536 do k1 = 1, n_profiles
537 atm(k1)%Temperature(1:n_layers) = geoval%vals(:, k1)
541 do k1 = 1, n_profiles
542 atm(k1)%Pressure(1:n_layers) = geoval%vals(:, k1) * 0.01
546 do k1 = 1, n_profiles
547 atm(k1)%Level_Pressure(:) = geoval%vals(:, k1) * 0.01
548 atm(k1)%Climatology = us_standard_atmosphere
551 do jspec = 1, conf%n_Absorbers
556 do k1 = 1, n_profiles
561 do k1 = 1, n_profiles
562 atm(k1)%Absorber(1:n_layers, jspec) = geoval%vals(:, k1)
565 do k1 = 1, n_profiles
566 atm(k1)%Absorber_Id(jspec) = conf%Absorber_Id(jspec)
567 atm(k1)%Absorber_Units(jspec) = conf%Absorber_Units(jspec)
571 do jspec = 1, conf%n_Clouds
574 do k1 = 1, n_profiles
575 atm(k1)%Cloud(jspec)%Water_Content = geoval%vals(:, k1)
576 atm(k1)%Cloud(jspec)%Type = conf%Cloud_Id(jspec)
581 do k1 = 1, n_profiles
582 atm(k1)%Cloud(jspec)%Effective_Radius = geoval%vals(:, k1)
590 if (conf%n_Clouds > 0)
then
591 if ( conf%Cloud_Fraction >= 0.0 )
then
592 do k1 = 1, n_profiles
593 atm(k1)%Cloud_Fraction(:) = conf%Cloud_Fraction
598 do k1 = 1, n_profiles
599 where( geoval%vals(:, k1) < 0_kind_real ) geoval%vals(:, k1) = 0_kind_real
600 where( geoval%vals(:, k1) > 1_kind_real ) geoval%vals(:, k1) = 1_kind_real
601 atm(k1)%Cloud_Fraction(:) = geoval%vals(:, k1)
611 subroutine load_sfc_data(n_Profiles, n_Channels, channels, geovals, sfc, chinfo, obss, conf)
615 integer,
intent(in) :: n_profiles, n_channels
617 type(crtm_surface_type),
intent(inout) :: sfc(:)
618 type(crtm_channelinfo_type),
intent(in) :: chinfo(:)
619 type(c_ptr),
value,
intent(in) :: obss
620 integer(c_int),
intent(in) :: channels(:)
629 integer,
parameter :: tundra_surface_type = 10
630 integer,
parameter :: scrub_surface_type = 7
631 integer,
parameter :: coarse_soil_type = 1
632 integer,
parameter :: groundcover_vegetation_type = 7
633 integer,
parameter :: bare_soil_vegetation_type = 11
634 integer,
parameter :: sea_water_type = 1
635 integer,
parameter :: fresh_snow_type = 2
636 integer,
parameter :: fresh_ice_type = 1
638 character(len=MAXVARLEN) :: varname
640 real(kind_real),
allocatable :: obstb(:,:)
642 allocate(obstb(n_profiles, n_channels))
643 obstb = 0.0_kind_real
645 do n1 = 1, n_channels
647 call obsspace_get_db(obss,
"ObsValue", varname, obstb(:, n1))
650 do k1 = 1, n_profiles
652 sfc(k1)%sensordata%sensor_id = chinfo(1)%sensor_id
653 sfc(k1)%sensordata%wmo_sensor_id = chinfo(1)%wmo_sensor_id
654 sfc(k1)%sensordata%wmo_satellite_id = chinfo(1)%wmo_satellite_id
655 sfc(k1)%sensordata%sensor_channel = channels
658 do n1 = 1, n_channels
659 sfc(k1)%sensordata%tb(n1) = obstb(k1, n1)
663 sfc(k1)%Water_Type = sea_water_type
672 do k1 = 1, n_profiles
673 sfc(k1)%Wind_Speed = geoval%vals(1, k1)
678 do k1 = 1, n_profiles
679 sfc(k1)%Wind_Direction = geoval%vals(1, k1)
688 do k1 = 1, n_profiles
689 sfc(k1)%Wind_Speed = sqrt(u%vals(1, k1)**2 + v%vals(1, k1)**2)
693 do k1 = 1, n_profiles
694 sfc(k1)%Wind_Direction =
uv_to_wdir(u%vals(1, k1), v%vals(1, k1))
697 call abor1_ftn(
'Load_Sfc_Data error: missing surface wind geovals')
702 do k1 = 1, n_profiles
703 sfc(k1)%Water_Coverage = geoval%vals(1, k1)
708 do k1 = 1, n_profiles
709 sfc(k1)%Water_Temperature = geoval%vals(1, k1)
714 do k1 = 1, n_profiles
715 sfc(k1)%Ice_Coverage = geoval%vals(1, k1)
720 do k1 = 1, n_profiles
721 sfc(k1)%Ice_Temperature = geoval%vals(1, k1)
726 do k1 = 1, n_profiles
727 sfc(k1)%Snow_Coverage = geoval%vals(1, k1)
732 do k1 = 1, n_profiles
733 sfc(k1)%Snow_Temperature = geoval%vals(1, k1)
738 do k1 = 1, n_profiles
739 sfc(k1)%Snow_Depth = geoval%vals(1, k1)
744 do k1 = 1, n_profiles
745 sfc(k1)%Land_Coverage = geoval%vals(1, k1)
752 do k1 = 1, n_profiles
753 iland = int(geoval%vals(1, k1))
754 if (.not.any(iland == conf%Land_WSI))
then
755 sfc(k1)%Land_Type = iland
761 do k1 = 1, n_profiles
762 sfc(k1)%Land_Temperature = geoval%vals(1, k1)
767 do k1 = 1, n_profiles
768 sfc(k1)%Lai = geoval%vals(1, k1)
773 do k1 = 1, n_profiles
774 sfc(k1)%Vegetation_Fraction = geoval%vals(1, k1)
779 do k1 = 1, n_profiles
780 sfc(k1)%Vegetation_Type = int(geoval%vals(1, k1))
785 do k1 = 1, n_profiles
786 sfc(k1)%Soil_Type = int(geoval%vals(1, k1))
791 do k1 = 1, n_profiles
792 sfc(k1)%Soil_Moisture_Content = geoval%vals(1, k1)
797 do k1 = 1, n_profiles
798 sfc(k1)%Soil_Temperature = geoval%vals(1, k1)
804 do k1 = 1, n_profiles
805 sfc(k1)%Salinity = geoval%vals(1, k1)
811 do k1 = 1, n_profiles
812 if (sfc(k1)%Land_Coverage > zero .and. &
813 (sfc(k1)%Soil_Type == 9 .or. sfc(k1)%Vegetation_Type == 13))
then
814 sfc(k1)%Ice_Coverage = min(sfc(k1)%Ice_Coverage + sfc(k1)%Land_Coverage, one)
815 sfc(k1)%Land_Coverage = zero
826 type(c_ptr),
value,
intent(in) :: obss
827 type(crtm_geometry_type),
intent(inout) :: geo(:)
828 type(crtm_geometry_type),
intent(inout),
optional :: geo_hf(:)
829 real(kind_real),
allocatable :: tmpvar(:)
831 character(kind=c_char,len=101) :: obsname
833 call obsspace_obsname(obss, obsname)
834 nlocs = obsspace_get_nlocs(obss)
835 allocate(tmpvar(nlocs))
837 call obsspace_get_db(obss,
"MetaData",
"sensor_zenith_angle", tmpvar)
838 geo(:)%Sensor_Zenith_Angle = abs(tmpvar(:))
840 call obsspace_get_db(obss,
"MetaData",
"solar_zenith_angle", tmpvar)
841 geo(:)%Source_Zenith_Angle = tmpvar(:)
843 call obsspace_get_db(obss,
"MetaData",
"sensor_azimuth_angle", tmpvar)
844 geo(:)%Sensor_Azimuth_Angle = tmpvar(:)
846 call obsspace_get_db(obss,
"MetaData",
"solar_azimuth_angle", tmpvar)
847 geo(:)%Source_Azimuth_Angle = tmpvar(:)
851 where (geo(:)%Source_Azimuth_Angle < 0.0_kind_real .or. &
852 geo(:)%Source_Azimuth_Angle > 360.0_kind_real) &
853 geo(:)%Source_Azimuth_Angle = 0.0_kind_real
854 where (geo(:)%Sensor_Azimuth_Angle < 0.0_kind_real .or. &
855 geo(:)%Sensor_Azimuth_Angle > 360.0_kind_real) &
856 geo(:)%Sensor_Azimuth_Angle = 0.0_kind_real
858 where (abs(geo(:)%Source_Zenith_Angle) > 180.0_kind_real) &
859 geo(:)%Source_Zenith_Angle = 100.0_kind_real
861 call obsspace_get_db(obss,
"MetaData",
"scan_position", tmpvar)
862 geo(:)%Ifov = tmpvar(:)
864 call obsspace_get_db(obss,
"MetaData",
"sensor_view_angle", tmpvar)
865 geo(:)%Sensor_Scan_Angle = tmpvar(:)
867 where (abs(geo(:)%Sensor_Scan_Angle) > 80.0_kind_real) &
868 geo(:)%Sensor_Scan_Angle = 0.0_kind_real
872 if (
present(geo_hf) )
then
874 if (obsspace_has(obss,
"MetaData",
"sensor_zenith_angle1"))
then
875 call obsspace_get_db(obss,
"MetaData",
"sensor_zenith_angle1", tmpvar)
876 geo_hf(:)%Sensor_Zenith_Angle = abs(tmpvar(:))
878 if (obsspace_has(obss,
"MetaData",
"solar_zenith_angle1"))
then
879 call obsspace_get_db(obss,
"MetaData",
"solar_zenith_angle1", tmpvar)
880 geo_hf(:)%Source_Zenith_Angle = tmpvar(:)
882 if (obsspace_has(obss,
"MetaData",
"sensor_azimuth_angle1"))
then
883 call obsspace_get_db(obss,
"MetaData",
"sensor_azimuth_angle1", tmpvar)
884 geo_hf(:)%Sensor_Azimuth_Angle = tmpvar(:)
886 if (obsspace_has(obss,
"MetaData",
"solar_azimuth_angle1"))
then
887 call obsspace_get_db(obss,
"MetaData",
"solar_azimuth_angle1", tmpvar)
888 geo_hf(:)%Source_Azimuth_Angle = tmpvar(:)
890 if (obsspace_has(obss,
"MetaData",
"sensor_view_angle1"))
then
891 call obsspace_get_db(obss,
"MetaData",
"sensor_view_angle1", tmpvar)
892 geo_hf(:)%Sensor_Scan_Angle = tmpvar(:)
905 integer,
intent(in) :: n
906 character(len=*),
intent(out) :: varname
908 character(len=6) :: chan
910 write(chan,
'(I0)') n
911 varname =
'brightness_temperature_' // trim(chan)
932 real(kind=kind_real),
intent(in) :: u
933 real(kind=kind_real),
intent(in) :: v
934 real(kind=kind_real) :: wdir
935 real(kind=kind_real) :: windratio, windangle
937 real(kind=kind_real),
parameter:: windscale = 999999.0_kind_real
938 real(kind=kind_real),
parameter:: windlimit = 0.0001_kind_real
939 real(kind=kind_real),
parameter:: quadcof(4,2) = &
943 if (u >=
zero .and. v >=
zero) iquadrant = 1
944 if (u >=
zero .and. v <
zero) iquadrant = 2
945 if (u <
zero .and. v >=
zero) iquadrant = 4
946 if (u <
zero .and. v <
zero) iquadrant = 3
948 if (abs(v) >= windlimit)
then
952 if (abs(u) > windlimit)
then
953 windratio = windscale * u
956 windangle = atan(abs(windratio))
957 wdir = ( quadcof(iquadrant, 1) *
pi + windangle * quadcof(iquadrant, 2) ) *
rad2deg
966 USE crtm_aerosolcoeff,
ONLY: aeroc
968 INTEGER,
INTENT(in) :: n_profiles,n_layers
970 TYPE(crtm_atmosphere_type),
INTENT(inout) :: atm(:)
972 CHARACTER(*) :: aerosol_option
973 CHARACTER(max_string) :: message
974 CHARACTER(len=MAXVARLEN) :: varname
978 CHARACTER(*),
PARAMETER :: routine_name =
'Load_Aerosol_Data'
980 REAL(kind_real),
DIMENSION(n_layers,n_profiles) :: rh
983 IF (
cmp_strings(aerosol_option,
"aerosols_gocart_default"))
THEN
986 rh(1:n_layers,1:n_profiles)=geoval%vals(1:n_layers,1:n_profiles)
987 WHERE (rh > 1_kind_real) rh=1_kind_real
989 ELSEIF (
cmp_strings(aerosol_option,
"aerosols_gocart_merra_2"))
THEN
992 rh(1:n_layers,1:n_profiles)=geoval%vals(1:n_layers,1:n_profiles)
993 WHERE (rh > 1_kind_real) rh=1_kind_real
995 ELSEIF (
cmp_strings(aerosol_option,
"aerosols_other"))
THEN
998 message =
'this aerosol not implemented - check later'
999 CALL display_message( aerosol_option, message, failure )
1007 INTEGER,
PARAMETER :: ndust_bins=5, nseas_bins=4
1008 REAL(kind_real),
DIMENSION(ndust_bins),
PARAMETER :: dust_radii=[&
1009 &0.55_kind_real,1.4_kind_real,2.4_kind_real,4.5_kind_real,8.0_kind_real]
1011 INTEGER,
DIMENSION(nseas_bins),
PARAMETER :: seas_types=[&
1012 seasalt_ssam_aerosol,seasalt_sscm1_aerosol,seasalt_sscm2_aerosol,seasalt_sscm3_aerosol]
1014 REAL(kind_real),
DIMENSION(n_layers) :: layer_factors
1018 CHARACTER(len=MAXVARLEN) :: varname
1029 atm(m)%aerosol(i)%Concentration(1:n_layers)=&
1032 SELECT CASE (trim(varname))
1034 atm(m)%aerosol(i)%type = sulfate_aerosol
1036 atm(m)%aerosol(i)%effective_radius(k)=&
1042 atm(m)%aerosol(i)%type = black_carbon_aerosol
1043 atm(m)%aerosol(i)%effective_radius(:)=&
1044 &aeroc%Reff(1,atm(m)%aerosol(i)%type)
1046 atm(m)%aerosol(i)%type = black_carbon_aerosol
1048 atm(m)%aerosol(i)%effective_radius(k)=&
1054 atm(m)%aerosol(i)%type = organic_carbon_aerosol
1055 atm(m)%aerosol(i)%effective_radius(:)=&
1056 &aeroc%Reff(1,atm(m)%aerosol(i)%type)
1058 atm(m)%aerosol(i)%type = organic_carbon_aerosol
1060 atm(m)%aerosol(i)%effective_radius(k)=&
1066 atm(m)%aerosol(i)%type = dust_aerosol
1067 atm(m)%aerosol(i)%effective_radius(:)=dust_radii(1)
1069 atm(m)%aerosol(i)%type = dust_aerosol
1070 atm(m)%aerosol(i)%effective_radius(:)=dust_radii(2)
1072 atm(m)%aerosol(i)%type = dust_aerosol
1073 atm(m)%aerosol(i)%effective_radius(:)=dust_radii(3)
1075 atm(m)%aerosol(i)%type = dust_aerosol
1076 atm(m)%aerosol(i)%effective_radius(:)=dust_radii(4)
1078 atm(m)%aerosol(i)%type = dust_aerosol
1079 atm(m)%aerosol(i)%effective_radius(:)=dust_radii(5)
1082 atm(m)%aerosol(i)%type = seas_types(1)
1084 atm(m)%aerosol(i)%effective_radius(k)=&
1089 atm(m)%aerosol(i)%type = seas_types(2)
1091 atm(m)%aerosol(i)%effective_radius(k)=&
1096 atm(m)%aerosol(i)%type = seas_types(3)
1098 atm(m)%aerosol(i)%effective_radius(k)=&
1103 atm(m)%aerosol(i)%type = seas_types(4)
1105 atm(m)%aerosol(i)%effective_radius(k)=&
1120 message =
'this aerosol not implemented in the CRTM - check later'
1121 CALL display_message( aerosol_option, message, failure )
1128 message =
'this aerosol not implemented - check later'
1129 CALL display_message( aerosol_option, message, failure )
1138 CHARACTER(*),
INTENT(in) :: aerosol_option
1139 CHARACTER(len=MAXVARLEN),
ALLOCATABLE,
INTENT(out) :: var_aerosols(:)
1141 CHARACTER(max_string) :: err_msg
1143 IF (aerosol_option ==
"aerosols_gocart_default")
THEN
1146 ELSEIF (aerosol_option ==
"aerosols_gocart_merra_2")
THEN
1149 ELSEIF (aerosol_option ==
"var_aerosols_other")
THEN
1153 WRITE(err_msg,*)
'assign_aerosol_names: aerosol_option not implemented '//trim(aerosol_option)
1154 call abor1_ftn(err_msg)
1161 TYPE(crtm_atmosphere_type),
INTENT(in) :: atm
1162 REAL(kind_real),
INTENT(out) :: layer_factors(:)
1166 DO k=1,
SIZE(layer_factors)
1170 layer_factors(k)=1e-9_kind_real*(atm%Level_Pressure(k)-&
1171 &atm%Level_Pressure(k-1))*100_kind_real/
grav/&
1172 &(1_kind_real+
rv_rd*atm%Absorber(k,1)*1e-3_kind_real)
1179 TYPE(crtm_atmosphere_type),
INTENT(in) :: atm(:)
1180 REAL(kind_real),
INTENT(out) :: layer_factors(:,:)
1184 DO k=1,
SIZE(layer_factors,1)
1185 DO m=1,
SIZE(layer_factors,2)
1189 layer_factors(k,m)=1e-9_kind_real*(atm(m)%Level_Pressure(k)-&
1190 &atm(m)%Level_Pressure(k-1))*100_kind_real/
grav/&
1191 &(1_kind_real+
rv_rd*atm(m)%Absorber(k,1)*1.e-3_kind_real)
1200 USE crtm_aerosolcoeff,
ONLY: aeroc
1206 INTEGER ,
INTENT(in) :: itype
1207 REAL(kind_real) ,
INTENT(in) :: rh
1210 REAL(kind_real) :: h1
1211 REAL(kind_real) :: r_eff
1215 IF ( rh <= aeroc%rh(1) )
THEN
1217 ELSE IF ( rh >= aeroc%rh(aeroc%n_rh) )
THEN
1220 DO m = 1, aeroc%n_rh-1
1221 IF ( rh < aeroc%rh(m+1) .AND. rh > aeroc%rh(m) )
THEN
1224 h1 = (rh-aeroc%rh(m))/(aeroc%rh(m+1)-aeroc%rh(m))
1231 r_eff = aeroc%reff(j1,itype )
1233 r_eff = (1_kind_real-h1)*aeroc%reff(j1,itype ) + h1*aeroc%reff(j2,itype )
1243 CHARACTER(*),
INTENT(in) :: str
1244 CHARACTER(LEN(str)) :: string
1248 CHARACTER(26),
PARAMETER :: upper =
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1249 CHARACTER(26),
PARAMETER :: lower =
'abcdefghijklmnopqrstuvwxyz'
1253 DO i = 1, len_trim(str)
1254 ic = index(upper, str(i:i))
1255 IF (ic > 0) string(i:i) = lower(ic:ic)
1262 CHARACTER(len=*),
INTENT(in) :: names(:)
1263 CHARACTER(len=*),
INTENT(in) :: usrname
1278 TYPE(crtm_atmosphere_type),
INTENT(in) :: atm(:)
1279 REAL(kind_real),
INTENT(out),
DIMENSION(:,:):: rh
1281 REAL,
ALLOCATABLE :: table(:),des(:)
1286 INTEGER i, k, it, n_layers, n_profiles
1289 n_profiles=
SIZE(rh,2)
1294 IF( .NOT.
ALLOCATED(table) )
CALL qsmith_init(table,des)
1298 ap1 = 10.*dim(atm(i)%Temperature(k), tmin) + 1.
1299 ap1 = min(2621., ap1)
1301 es = table(it) + (ap1-it)*des(it)
1302 q=atm(i)%Absorber(k,1)*1.e-3/(1.+atm(i)%Absorber(k,1)*1.e-3)
1303 qs =
esl*es*(1.+
zvir*q)/(atm(i)%Pressure(k)*100.)
1312 REAL(kind_real),
DIMENSION(:,:),
INTENT(in) :: t,sphum,p
1313 REAL(kind_real),
DIMENSION(:,:),
INTENT(out) :: rh
1315 REAL,
ALLOCATABLE :: table(:),des(:)
1320 INTEGER i, k, it, n_layers, n_profiles
1323 n_profiles=
SIZE(t,2)
1328 IF ( .NOT.
ALLOCATED(table) )
CALL qsmith_init(table,des)
1332 ap1 = 10.*dim(t(k,i), tmin) + 1.
1333 ap1 = min(2621., ap1)
1335 es = table(it) + (ap1-it)*des(it)
1337 qs =
esl*es*(1.+
zvir*q)/p(k,i)
1346 REAL,
ALLOCATABLE,
INTENT(out) :: table(:),des(:)
1347 INTEGER,
PARAMETER:: length=2621
1350 IF( .NOT.
ALLOCATED(table) )
THEN
1353 ALLOCATE ( table(length) )
1354 ALLOCATE ( des(length) )
1359 des(i) = table(i+1) - table(i)
1361 des(length) = des(length-1)
1367 INTEGER,
INTENT(in):: n
1370 REAL esbasw, tbasw, tbasi, Tmin, tem, aa, b, c, d, e
1380 tem = tmin+dt*real(i-1)
1381 aa = -7.90298*(tbasw/tem-1)
1382 b = 5.02808*alog10(tbasw/tem)
1383 c = -1.3816e-07*(10**((1-tem/tbasw)*11.344)-1)
1384 d = 8.1328e-03*(10**((tbasw/tem-1)*(-3.49149))-1)
1386 table(i) = 0.1*10**(aa+b+c+d+e)
real(kind_real), parameter, public pi
real(kind_real), parameter, public one
real(kind_real), parameter, public zero
real(kind_real), parameter, public two
real(kind_real), parameter, public rad2deg
Fortran module to provide code shared between nonlinear and tlm/adm radiance calculations.
integer, dimension(n_valid_cloud_categories), parameter crtm_cloud_id
subroutine qsmith_profiles(t, sphum, p, rh)
character(len=maxvarlen), dimension(4), parameter ufo_surfaces
subroutine, public crtm_conf_setup(conf, f_confOpts, f_confOper)
real(kind_real), parameter zvir
character(len=maxvarlen), dimension(n_valid_absorber_ids), parameter crtm_absorbers
character(len=maxvarlen), dimension(n_valid_cloud_categories, 2), parameter ufo_clouds
subroutine qs_table(n, table)
real(kind_real), parameter, public grav
integer, parameter, public max_string
integer, dimension(3), parameter crtm_absorber_units
real(kind_real), parameter, public aerosol_concentration_minvalue_layer
subroutine, public get_var_name(n, varname)
character(len=maxvarlen), dimension(2), parameter validsurfacewindgeovars
character(len=maxvarlen), dimension(3), parameter ufo_absorbers
integer function getindex(names, usrname)
character(len=maxvarlen), dimension(n_valid_cloud_categories), parameter crtm_clouds
character(len(str)) function, public upper2lower(str)
real(kind_real), parameter tice
subroutine, public load_aerosol_data(n_profiles, n_layers, geovals, aerosol_option, atm)
real(kind_real), parameter ozone_default_value
subroutine, public load_geom_data(obss, geo, geo_hf)
subroutine calculate_aero_layer_factor_atm_profile(atm, layer_factors)
real(kind_real), parameter, public aerosol_concentration_minvalue
subroutine, public crtm_comm_stat_check(stat, PROGRAM_NAME, message, f_comm)
subroutine, public load_sfc_data(n_Profiles, n_Channels, channels, geovals, sfc, chinfo, obss, conf)
subroutine, public ufo_crtm_skip_profiles(n_Profiles, n_Channels, channels, obss, Skip_Profiles)
subroutine, public assign_aerosol_names(aerosol_option, var_aerosols)
real(kind_real), parameter, public rv_rd
real(kind_real), parameter esl
real(kind_real) function gocart_aerosol_size(itype, rh)
real(kind=kind_real) function uv_to_wdir(u, v)
Determines the wind direction from U and V components.
subroutine qsmith_atm(atm, rh)
subroutine calculate_aero_layer_factor_atm(atm, layer_factors)
subroutine, public crtm_conf_delete(conf)
integer, dimension(n_valid_absorber_ids), parameter crtm_absorber_id
subroutine qsmith_init(table, des)
character(len=maxvarlen), dimension(4), parameter crtm_surfaces
subroutine, public load_atm_data(n_Profiles, n_Layers, geovals, atm, conf)
subroutine, public ufo_geovals_get_var(self, varname, geoval)
Fortran module with various useful routines.
logical function, public cmp_strings(str1, str2)
character(len=maxvarlen), parameter, public var_co2
character(len=maxvarlen), parameter, public var_prsi
character(len=maxvarlen), dimension(n_aerosols_other), parameter, public var_aerosols_other
character(len=maxvarlen), parameter, public var_clrefr
character(len=maxvarlen), parameter, public var_clsefr
character(len=maxvarlen), parameter, public var_sfc_ifrac
integer function, public ufo_vars_getindex(vars, varname)
character(len=maxvarlen), parameter, public var_cldfrac
character(len=maxvarlen), parameter, public var_oz
character(len=maxvarlen), parameter, public var_clgefr
character(len=maxvarlen), parameter, public var_clw
character(len=maxvarlen), parameter, public var_sfc_lfrac
character(len=maxvarlen), parameter, public var_cls
character(len=maxvarlen), parameter, public var_sfc_wtmp
character(len=maxvarlen), parameter, public var_prs
character(len=maxvarlen), parameter, public var_rh
character(len=maxvarlen), parameter, public var_du004
character(len=maxvarlen), parameter, public var_sfc_wfrac
character(len=maxvarlen), parameter, public var_sfc_sfrac
character(len=maxvarlen), parameter, public var_sfc_itmp
character(len=maxvarlen), parameter, public var_sfc_wdir
character(len=maxvarlen), parameter, public var_bcphilic
character(len=maxvarlen), parameter, public var_sfc_soilm
integer, parameter, public n_aerosols_gocart_default
character(len=maxvarlen), parameter, public var_clhefr
character(len=maxvarlen), parameter, public var_du005
integer, parameter, public maxvarlen
character(len=maxvarlen), parameter, public var_ocphobic
character(len=maxvarlen), parameter, public var_sfc_u
character(len=maxvarlen), parameter, public var_sfc_sdepth
character(len=maxvarlen), parameter, public var_du003
character(len=maxvarlen), parameter, public var_sfc_landtyp
character(len=maxvarlen), parameter, public var_mixr
character(len=maxvarlen), parameter, public var_clh
character(len=maxvarlen), parameter, public var_du002
character(len=maxvarlen), dimension(n_aerosols_gocart_merra_2), parameter, public var_aerosols_gocart_merra_2
character(len=maxvarlen), parameter, public var_sulfate
character(len=maxvarlen), parameter, public var_bcphobic
character(len=maxvarlen), parameter, public var_sfc_stmp
character(len=maxvarlen), parameter, public var_cliefr
character(len=maxvarlen), parameter, public var_sfc_sss
character(len=maxvarlen), parameter, public var_ts
character(len=maxvarlen), parameter, public var_sfc_lai
character(len=maxvarlen), parameter, public var_ocphilic
character(len=maxvarlen), parameter, public var_clwefr
character(len=maxvarlen), parameter, public var_du001
character(len=maxvarlen), parameter, public var_sfc_v
character(len=maxvarlen), parameter, public var_sfc_vegtyp
character(len=maxvarlen), parameter, public var_sfc_soiltyp
character(len=maxvarlen), parameter, public var_cli
character(len=maxvarlen), dimension(n_aerosols_gocart_default), parameter, public var_aerosols_gocart_default
character(len=maxvarlen), parameter, public var_ss002
character(len=maxvarlen), parameter, public var_sfc_vegfrac
character(len=maxvarlen), parameter, public var_clr
character(len=maxvarlen), parameter, public var_sfc_ltmp
character(len=maxvarlen), parameter, public var_ss004
character(len=maxvarlen), parameter, public var_sfc_soilt
character(len=maxvarlen), parameter, public var_sfc_wspeed
character(len=maxvarlen), parameter, public var_ss003
character(len=maxvarlen), parameter, public var_ss001
character(len=maxvarlen), parameter, public var_clg
type to hold interpolated field for one variable, one observation
type to hold interpolated fields required by the obs operators
subroutine assign_gocart_merra_2
subroutine assign_gocart_default