|
|
◆ grid_transform_levtype_levtype_init()
| subroutine grid_transform_levtype_levtype_init |
( |
type(grid_transform), intent(out) |
this, |
|
|
type(transform_def), intent(in) |
trans, |
|
|
type(vol7d_level), dimension(:), intent(in) |
lev_in, |
|
|
type(vol7d_level), dimension(:), intent(in) |
lev_out, |
|
|
real, dimension(:,:,:), intent(inout), optional, allocatable |
coord_3d_in, |
|
|
character(len=*), intent(in), optional |
categoryappend |
|
) |
| |
Constructor for a grid_transform object, defining a particular vertical transformation.
It defines an object describing a transformation involving operations on the vertical direction only, thus it applies in the same way to grid-to-grid and to sparse points-to-sparse points transformations; the abstract type of the transformation is described in the transformation object trans (type transform_def) which must have been properly initialised. The additional information required here is the list of input and output levels and an optional 3-d field indicating the vertical coordinates of the input dataset.
The input level list lev_in is a 1-d array of vol7d_level type, describing the vertical coordinate system of the whole input dataset, only the vertical levels or layers matching the level type indicated when initialising the transformation object trans will be used, the others will be discarded in the vertical transformation. However the relevant vertical levels must be contiguous and sorted accordingly to the default vol7d_level sort order. The argument lev_out describes the vertical coordinate system of the output dataset. A particular case to be considered is when SIZE(lev_out)==0, this means that the output coordinates have to be computed automatically in the current subroutine, this is supported only for hybrid levels/layers.
When the input and output level types are different, the coord_3d_in array must be provided, indicating the vertical coordinate of every input grid point expressed in terms of the output vertical coordinate system (e.g. height if interpolating to constant height levels or pressure if interpolating to isobaric levels). This array must contain, in the 3rd vertical dimension, only the those levels/layers of lev_in that are actually used for interpolation. The storage space of coord_3d_in is "stolen" by this method, so the array will appear as unallocated and unusable to the calling procedure after return from this subroutine.
Layers in the grib2 sense (i.e. layers between two surfaces) can be handled by this class only when the upper and lower surfaces are of the same type; in these cases the coordinate assigned to every layer fro interpolation is the average (or log-average in case of isobaric surfaces) between the coordinates of the corresponding upper and lower surfaces.
- Parametri
-
| [out] | this | grid_transformation object |
| [in] | trans | transformation object |
| [in] | lev_in | vol7d_level from input object |
| [in] | lev_out | vol7d_level object defining target vertical grid |
| [in,out] | coord_3d_in | vertical coordinates of each input point in target reference system |
| [in] | categoryappend | append this suffix to log4fortran namespace category |
Definizione alla linea 1096 del file grid_transform_class.F90.
1096 ') suitable for interpolation') 1102 IF (this%trans%sub_type == 'linear') THEN 1104 ALLOCATE(this%inter_index_z(this%outnz), this%inter_zp(this%outnz)) 1105 this%inter_index_z(:) = imiss 1106 this%inter_zp(:) = dmiss 1107 IF (this%trans%extrap .AND. istart > 0) THEN 1110 this%inter_index_z(:) = istart 1111 this%inter_zp(:) = 1.0d0 1116 outlev: DO j = ostart, oend 1117 inlev: DO i = icache, iend 1118 IF (coord_in(i) >= coord_out(j)) THEN 1119 IF (coord_out(j) >= coord_in(i-1)) THEN 1120 this%inter_index_z(j) = i - 1 1121 this%inter_zp(j) = (coord_out(j)-coord_in(i-1)) / & 1122 (coord_in(i)-coord_in(i-1)) 1129 IF (this%trans%extrap .AND. iend > 1) THEN 1130 this%inter_index_z(j) = iend - 1 1131 this%inter_zp(j) = 0.0d0 1135 DEALLOCATE(coord_out, mask_out) 1138 ELSE IF (this%trans%sub_type == 'linearsparse') THEN 1140 ALLOCATE(this%vcoord_in(this%levused), this%vcoord_out( SIZE(coord_out))) 1141 this%vcoord_in(:) = coord_in(this%levshift+1:this%levshift+this%levused) 1142 this%vcoord_out(:) = coord_out(:) 1143 DEALLOCATE(coord_out, mask_out) 1154 END SUBROUTINE grid_transform_levtype_levtype_init 1159 SUBROUTINE make_vert_coord(lev, mask, coord, dolog) 1160 TYPE(vol7d_level), INTENT(in) :: lev(:) 1161 LOGICAL, INTENT(inout) :: mask(:) 1162 DOUBLE PRECISION, INTENT(out) :: coord(:) 1163 LOGICAL, INTENT(out) :: dolog 1166 DOUBLE PRECISION :: fact 1173 IF (any(lev(k)%level1 == height_level)) THEN 1175 ELSE IF (any(lev(k)%level1 == thermo_level)) THEN 1177 ELSE IF (any(lev(k)%level1 == sigma_level)) THEN 1183 IF (c_e(lev(k)%level2) .AND. lev(k)%level1 == lev(k)%level2) THEN 1184 IF (lev(k)%level1 == 100 .OR. lev(k)%level1 == 108) THEN 1185 WHERE(mask(:) .AND. lev(:)%l1 > 0 .AND. lev(:)%l2 > 0) 1186 coord(:) = (log(dble(lev(:)%l1)*fact) + log(dble(lev(:)%l2)*fact))*0.5d0 1191 coord(:) = (lev(:)%l1 + lev(:)%l2)*fact*0.5d0 1195 IF (lev(k)%level1 == 100 .OR. lev(k)%level1 == 108) THEN 1196 WHERE(mask(:) .AND. lev(:)%l1 > 0) 1197 coord(:) = log(dble(lev(:)%l1)*fact) 1202 coord(:) = lev(:)%l1*fact 1208 mask(:) = mask(:) .AND. c_e(coord(:)) 1210 END SUBROUTINE make_vert_coord 1230 SUBROUTINE grid_transform_init(this, trans, in, out, maskgrid, maskbounds, & 1232 TYPE(grid_transform), INTENT(out) :: this 1233 TYPE(transform_def), INTENT(in) :: trans 1234 TYPE(griddim_def), INTENT(inout) :: in 1235 TYPE(griddim_def), INTENT(inout) :: out 1236 REAL, INTENT(in), OPTIONAL :: maskgrid(:,:) 1237 REAL, INTENT(in), OPTIONAL :: maskbounds(:) 1238 CHARACTER(len=*), INTENT(in), OPTIONAL :: categoryappend 1240 INTEGER :: nx, ny, i, j, ix, iy, n, nm, nr, cf_i, cf_o, nprev, & 1241 xnmin, xnmax, ynmin, ynmax 1242 DOUBLE PRECISION :: xmin, xmax, ymin, ymax, steplon, steplat, & 1243 xmin_new, ymin_new, ellips_smaj_axis, ellips_flatt, r2 1244 TYPE(geo_proj) :: proj_in, proj_out 1245 TYPE(georef_coord) :: point 1246 LOGICAL, ALLOCATABLE :: point_mask(:,:) 1247 TYPE(griddim_def) :: lin, lout 1250 CALL grid_transform_init_common(this, trans, categoryappend) 1252 CALL l4f_category_log(this%category, l4f_debug, "grid_transform vg6d-vg6d") 1256 CALL get_val(in, ellips_smaj_axis=ellips_smaj_axis, ellips_flatt=ellips_flatt) 1257 CALL set_val(out, ellips_smaj_axis=ellips_smaj_axis, ellips_flatt=ellips_flatt) 1259 IF (this%trans%trans_type == 'zoom') THEN 1261 IF (this%trans%sub_type == 'coord') THEN 1263 CALL griddim_zoom_coord(in, & 1264 this%trans%rect_coo%ilon, this%trans%rect_coo%ilat,& 1265 this%trans%rect_coo%flon, this%trans%rect_coo%flat,& 1266 this%trans%rect_ind%ix, this%trans%rect_ind%iy, & 1267 this%trans%rect_ind%fx, this%trans%rect_ind%fy) 1269 ELSE IF (this%trans%sub_type == 'projcoord') THEN 1271 CALL griddim_zoom_projcoord(in, & 1272 this%trans%rect_coo%ilon, this%trans%rect_coo%ilat,& 1273 this%trans%rect_coo%flon, this%trans%rect_coo%flat,& 1274 this%trans%rect_ind%ix, this%trans%rect_ind%iy, & 1275 this%trans%rect_ind%fx, this%trans%rect_ind%fy) 1277 ELSE IF (this%trans%sub_type == 'coordbb') THEN 1282 CALL get_val(lin, nx=nx, ny=ny) 1284 ALLOCATE(point_mask(nx,ny)) 1285 point_mask(:,:) = .false. 1291 IF (lin%dim%lon(i,j) > this%trans%rect_coo%ilon .AND. & 1292 lin%dim%lon(i,j) < this%trans%rect_coo%flon .AND. & 1293 lin%dim%lat(i,j) > this%trans%rect_coo%ilat .AND. & 1294 lin%dim%lat(i,j) < this%trans%rect_coo%flat) THEN 1295 point_mask(i,j) = .true. 1302 IF (any(point_mask(i,:))) EXIT 1304 this%trans%rect_ind%ix = i 1305 DO i = nx, this%trans%rect_ind%ix, -1 1306 IF (any(point_mask(i,:))) EXIT 1308 this%trans%rect_ind%fx = i 1311 IF (any(point_mask(:,j))) EXIT 1313 this%trans%rect_ind%iy = j 1314 DO j = ny, this%trans%rect_ind%iy, -1 1315 IF (any(point_mask(:,j))) EXIT 1317 this%trans%rect_ind%fy = j 1319 DEALLOCATE(point_mask) 1321 IF (this%trans%rect_ind%ix > this%trans%rect_ind%fx .OR. & 1322 this%trans%rect_ind%iy > this%trans%rect_ind%fy) THEN 1324 CALL l4f_category_log(this%category,l4f_error, & 1325 "zoom coordbb: no points inside bounding box "//& 1326 trim(to_char(this%trans%rect_coo%ilon))// ","// & 1327 trim(to_char(this%trans%rect_coo%flon))// ","// & 1328 trim(to_char(this%trans%rect_coo%ilat))// ","// & 1329 trim(to_char(this%trans%rect_coo%flat))) 1338 CALL get_val(in, nx=nx, ny=ny, xmin=xmin, xmax=xmax, & 1339 ymin=ymin, ymax=ymax, dx=steplon, dy=steplat) 1342 this%iniox = min(max(this%trans%rect_ind%ix,1),nx) 1343 this%inioy = min(max(this%trans%rect_ind%iy,1),ny) 1344 this%infox = max(min(this%trans%rect_ind%fx,nx),1) 1345 this%infoy = max(min(this%trans%rect_ind%fy,ny),1) 1347 this%outinx = min(max(2-this%trans%rect_ind%ix,1),nx) 1348 this%outiny = min(max(2-this%trans%rect_ind%iy,1),ny) 1349 this%outfnx = min(this%trans%rect_ind%fx,nx)-this%trans%rect_ind%ix+1 1350 this%outfny = min(this%trans%rect_ind%fy,ny)-this%trans%rect_ind%iy+1
|