presProfileOperators_mod¶
Dependency Diagrams:
Description
MODULE presProfileOperators_mod (prefix=’ppo’ category=’8. Low-level utilities and constants’)
- Purpose
Vertical interpolation, integration, and layer averaging subroutines. Includes the special routines designed to interpolate to the (widely spaced) RTTOV pressure levels.
Quick access
- Routines
ppo_getlevelindex()
,ppo_layeravginterpwgts()
,ppo_lintv()
,ppo_piecewiselinearwgts()
,ppo_sublayerinterpwgts()
,ppo_vertavgwgts()
,ppo_vertintegwgts()
,ppo_vertinterpwgts()
,ppo_vertlayerssetup()
Needed modules
utilities_mod
: MODULE utilities_mod (prefix=’utl’ category=’8. Low-level utilities and constants’)Variables
Subroutines and functions
- subroutine presprofileoperators_mod/ppo_lintv(pvlev, pvi, kni, knprof, kno, ppo, pvo)¶
- Purpose
To perform the vertical interpolation in log of pressure and constant-value extrapolation of one-dimensional vectors. Input pressure levels can vary for each profile.
- Arguments
pvlev (kni,knprof) [real ,in] :: Vertical levels, pressure (source)
pvi (kni,knprof) [real ,in] :: Vector to be interpolated (source)
kni [integer ,in,] :: Number of input levels (source)
knprof [integer ,in,] :: Number of profiles
kno [integer ,in,] :: Number of output levels (destination)
ppo (kno,knprof) [real ,in] :: Vertical levels, pressure (destination)
pvo (kno,knprof) [real ,out] :: Interpolated profiles (destination)
- Called from
- subroutine presprofileoperators_mod/ppo_vertinterpwgts(pressinput, presstarget, numinputlevs, numtargetlevs, wgts, kstart, kend[, method_opt[, skiptype_opt[, outbound_opt[, success_opt]]]])¶
- Purpose
Determination of interpolation weights for interpolation to points in a profile. Applies interpolation in log(Pressure).
- Input
- pressInput
pressure on reference column levels assumed to be in ascending order
- pressTarget
target pressure levels assumed to be in ascending order
- numInputLevs
number of input/reference levels
- numTargetLevs
number of target levels
- Options
method_opt [character ,in,] ::
Specified interpolation method :skipType_opt: Skipping processing of specific target levels depending on case:
’default’ - extrapolation allowed and skipping application via input success_opt only ‘noExtrap’ - no extrapolation as well as additional skipping via input success_opt ‘doAll&noExtrap’ - no extrapolation only (all other levels processed)
skiptype_opt [character ,in,] :: Skipping processing of specific target levels depending on case
- Inout
- Arguments
outbound_opt (numtargetlevs) [integer ,inout,] :: Flag indicating if obs outside model vertical range (0 for no)
success_opt (numtargetlevs) [logical ,inout,] :: success of interpolation
wgts (numtargetlevs,numinputlevs) [real ,out] :: Averaging weights
kstart (numtargetlevs) [integer ,out] :: Index of first relevant original/input level for each target level
kend (numtargetlevs) [integer ,out] :: Index of last relevant original/input level for each target level
pressinput (numinputlevs) [real ,in] :: pressure on reference column levels assumed in ascending order
presstarget (numtargetlevs) [real ,in] :: target pressure levels assumed to be in ascending order
numinputlevs [integer ,in,] :: # of original/input vertical levels
numtargetlevs [integer ,in,] :: # of target vertical levels
- Output
- Call to
ppo_piecewiselinearwgts()
,ppo_layeravginterpwgts()
,utl_abort()
- subroutine presprofileoperators_mod/ppo_piecewiselinearwgts(pvo, pvi, kno, kni, wgts, kstart[, validlevel_opt])¶
- Purpose
To obtain peacewise linear interpolation weigths. Assumes pv*(i) < pv*(i+1). Constant values extrapolation is applied.
- Arguments
pvo (kno) [real ,in] :: Vertical levels, pressure (destination)
pvi (kni) [real ,in] :: Vertical levels, pressure (source)
kno [integer ,in,] :: Number of output levels (destination)
kni [integer ,in,] :: Number of input levels (source)
wgts (kno,2) [real ,out] :: Interpolation weights (destination)
kstart (kno) [integer ,out] :: Index i of pvlev level associated to pvo(j,1); pvo(j,2) is for pvlev level i+1
validlevel_opt (kno) [logical ,out,]
- Called from
- subroutine presprofileoperators_mod/ppo_layeravginterpwgts(px1, px2, kn1, kn2, pz, kstart, kend[, pzs1_opt[, pzs2_opt[, pzdps_opt[, rttov_opt[, validlevel_opt]]]]])¶
- Purpose
Determine profile interpolation weights by considering integrations over of series of segments [PX1(KI-1),PX1(KI+1)] using piecewise linear weighting with weights of zero at KI-1 and KI+1 and max weight at KI. KI ranges from 1 to KN1.
Can also provide gradient contributions from both linear and non-linear components of interpolator. The non-linear components (case PZS* is present) stem from vertical coordinate independent variables (e.g. dependency on Ps). The gradients contributions from the linear components are the interpolation weights.
For the interpolation model f(x) where
- f(v,x) = F(v)*x
~ F(vo)*xo + F(vo)*(x-xo) + (dF/dv)*xo*(v-vo) = F(vo)*x + (dF/dv)*xo*(v-vo) (eqn 1)
- F(vo): array of interpolation weights
= array of gradients from the linear component
- (dF/dv)*xo:
array of gradients from linearized component. (dF/dv) or (dF/dv)*(v-vo) provided when pzs* is present
- Method:
Piecewise weighted interpolation in ln(P).
Journal reference: Rochon, Y.J., L. Garand, D.S. Turner, and S. Polavarapu. Jacobian mapping between coordinate systems in data assimilation, Q. J. of the Royal Met. Soc., vol 133, 1547-1558, 2007. (www.interscience.wiley.com) DOI:10.1002/qj.117
URL: http://www3.interscience.wiley.com/cgi-bin/fulltext/116320452/PDFSTART
- Comments
Assumption: PX1(i)<PX1(i+1) & PX2(i)<PX2(i+1)
The input profile is now extrapolated at constant value.
The impact is of most practical significance for instruments where the weighting function peaks at or near the surface such as SSMI.
This approach increases the weights of contribution from the lowest and highest input domain levels for output layers intersecting these input domain boundaries. It consists of applying contant value extrapolation by introducing ‘fake’ or ‘virtual’ layers. For the lowest level of the input domain, as example, this implies creating a virtual surface layer which extends to the lower boundary of the output domain layer which contains the input domain surface. This increases the contributing weight of the surface which would be otherwise understimated in the original code due to the interpolator actually doing piecewise weighted averaging.
COmment out use of ‘zb’ for consistency with RTTOV-9 when
- Options
rttov_opt [logical ,in,] ::
Commented out use of ‘zb’ when .true. for consistency with RTTOV-9 See the four lines ending with !C1 and version 7 comment above.
3) A major reduction in computational time results from only assigning values to the non-zero ranges of the 2D output arrays. These ranges of the 2D areas are identified by ‘kstart’ and ‘kend’. Initialization to zero for values within these ranges is done using 1D work arrays ‘zpz’ and ‘zpzd’, with the resulting values then being assigned to the related elements of ‘PZ’ and ‘PZDPS’.
Therefore, elements of ‘PZ’ and ‘PZDPS’ outside these ranges could be undefined (i.e. NaN if not 0.0) and should not be used.
Other notable reductions in computational time stem (a) from inlining of ‘sublayer’ code (applied to a reduced degree in ‘layeravg’ as compared to ‘rttov_layeravg_*) and (b) from updating the start position ‘istart’ of the loops over J. The latter was faciliated by moving the loop over KI inside ‘layeravg’.
These improvements were originally devised and implemented by Deborah Salmond and Mats Hamrud (ECMWF) in the RTTOV-9 routines ‘rttov_layeravg*’.
4) Contributors to improvements and changes to the original version of ‘layeravg’ and to ‘rttov_layeravg*’: members of the RTTOV9 development team, namely Niels Bormann, Alan Geer, Deborah Salmond, and Mats Hamrud of ECMWF, Peter Rayer and Roger Saunders of the Met Office and Pascal Brunel of Meteo-France, and Y.J. Rochon (EC).
- Arguments
px1 (kn1) [real ,in] :: Levels of output domain (e.g. lnP; in increasing values)
px2 (kn2) [real ,in] :: Levels of input domain (e.g. lnP; in increasing values)
kn1 [integer ,in,] :: Dimension of PX1
kn2 [integer ,in,] :: Dimension of other arrays
pz (kn1,kn2) [real ,out] :: Resultant accumulated weighting factors for interp from input to output domain
kstart (kn1) [integer ,out] :: Start index for relevant PZ row
kend (kn1) [integer ,out] :: End index of relevant PZ row
pzs1_opt (kn1) [real ,in,] :: dPX1/dv or perturbation dPX1/dv * delta(v) where PX1(v), e.g. v=Ps
pzs2_opt (kn2) [real ,in,] :: dPX2/dv or perturbation dPX2/dv * delta(v) where PX2(v), e.g. v=Ps
pzdps_opt (kn1,kn2) [real ,out,] :: dF/dv or perturbations (dF/dv)*(v-vo): Resultant accumulated factors for the gradients w.r.t. v (or perturbations) associated to coordinates
validlevel_opt (kn1) [logical ,in,] :: Logical indicating validity of each output level
- Called from
- Call to
- subroutine presprofileoperators_mod/ppo_sublayerinterpwgts(z1, z2, dzd, wgt1, wgt2, x1, x2, dxd, w1, w2, pzs1, pzs2, pxs1, pxs2, wps1, wps2, lgradpx, lgradpz)¶
- Purpose
Determine weight coefficient contributions to w1 and w2 to assign to input domain (e.g. NWP model) variables at x1 and x2. Weights are determined from integration over the intersecting segment (y1,y2) of the ranges (x1,x2) for the input domain and (z1,z2) for the output domain. Integrals are approximated via the trapezoidal rule:
integral of f(x)=w(x)*t(x) from y1 to y2
= (f(y1)+f(y2))/2*(y2-y1) = w(y1)*t(y1)+w(y2)*t(y2) = w1*t(x1)+w2*t(x2) = w1*t1+w2*t2
This is synonomous to having an integrand linear in x.
In the above (and below) equation(s), w1 and w2 are contributions to the input values.
The weights for linearized contributions of non-linear interpolator components, i.e. gradient w.r.t. the vertical coordinate independent variable (e.g. v*=Ps), are calculated when LGRADP* is .true.:
- pzps = pzps + (df/dx1)*(dx1/dvx1)+(df/dx2)*(dx2/dvx2)
(df/dz1)*(dz1/dvz1)+(df/dz2)*(dz2/dvz2)
- = pzpz + (dw1/dx1*t1+dw2/dx1*t2)*pxs1
(dw1/dx2*t1+dw2/dx2*t2)*pxs2
(dw1/dz1*t1+dw2/dz1*t2)*pzs1
(dw1/dz2*t1+dw2/dz2*t2)*pzs2
This routine provides terms on the right-hand-side.
Note: pxs* and pzs* can be provided either as gradients or perturbations.
Method: - Piecewise weighted interpolation in ln(P). - Journal reference:
Rochon, Y.J., L. Garand, D.S. Turner, and S. Polavarapu. Jacobian mapping between coordinate systems in data assimilation, Q. J. of the Royal Met. Soc., vol 133, 1547-1558, 2007. (www.interscience.wiley.com) DOI:10.1002/qj.117
URL: http://www3.interscience.wiley.com/cgi-bin/fulltext/116320452/PDFSTART
- Comments
Assumptions:
x1<x2
z1<z2
3) The ranges (z1,z2) and (x1,x2) overlap. The overlap region will be identified as (y1,y2) with y1<y2.
1) w(y1) and w(y2) are obtained by linear interpolation of the linear weighting function w with w(z1)=wgt1 and w(z2)=wgt2.
2) The w1 and w2 above are determined by expanding t(y1) and t(y2) as linear functions of t(x1)=t1 and t(x2)=t2.
The factor of 1/2 in
- (f(y1)+f(y2))/2*(y2-y1)
= w(y1)*t(y1)+w(y2)*t(y2)
is omitted as normalization is performed in the calling routine LAYERAVG.
4) The code version of the interpolator part of ‘int_sublayerInterpWgts’ provided for RTTOV-9 assumed the following conditions:
- (wgt1,wgt2)=(0,1), d1=(y1-x1)=0 from y1=x1 or
wy1=0 from wgt1=0 and y1=z1,
or
- (wgt1,wgt2)=(1,0), d2=(y2-x2)=0 when y2=x2 or
wy2=0 from wgt2=0 and y2=z2
and took account of the implications on d* and wy*.
The version presented here has each step accompanied by related equations. It does not assume the above restrictions on
- Arguments
wgt1 [real ,in] ::
Weight at z1 (0.0 or 1.0 or …) comments section of the RTTOV-9 module ‘rttov_sublayer’.
5) When LGRADP*=.true., this routine provides terms needed for the gradients w.r.t.the vertical coordinate independent variable, e.g. Ps.
z1 [real ,in] :: Upper level of output domain half-layer (z1<z2)
z2 [real ,in] :: Lower level of output domain half-layer
dzd [real ,in] :: 1.0/(z2-z1)=1.0/dz
wgt2 [real ,in] :: Weight at z2 (1.0 or 0.0 or …)
x1 [real ,in] :: Upper boundary of input layer (x1<x2)
x2 [real ,in] :: Lower boundary of input layer
dxd [real ,in] :: 1.0/(x2-x1)=1.0/dx
w1 [real ,inout] :: Starting (in) and updated (out) weight assigned to variable at upper level x1
w2 [real ,inout] :: Starting (in) and updated (out) weight assigned to variable at upper level x2
pzs1 [real ,in] :: dz1/dvz or perturbation dz1/dvz * delta(vz)
pzs2 [real ,in] :: dz2/dvz or perturbation dz2/dvz * delta(vz)
pxs1 [real ,in] :: dx1/dvx or perturbation dx1/dvx * delta(vx) (required when LGRADPx=.true.)
pxs2 [real ,in] :: dx2/dvx or perturbation dx2/dvx * delta(vx)
wps1 [real ,inout] :: Starting (in) and updated (out) value of (pxs1*dw1/dx1 + pxs2*dw1/dx2 +pzs1*dw1/dz1 + pzs2*dw1/dz2)
wps2 [real ,inout] :: Starting (in) and updated (out) value of pxs1*dw2/dx1 + pxs2*dw2/dx2 +pzs1*dw2/dz1 + pzs2*dw2/dz2) (required when LGRADP*=.true.)
lgradpx [logical ,in] :: Input domain logical indicating if gradient w.r.t. vertical coordinate independent variable if required i.e. d/dv where P(v) (e.g. v=Ps).
lgradpz [logical ,in] :: Output domain logical indicating if gradient w.r.t. vertical coordinate independent variable if required i.e. d/dv where P(v) (e.g. v=Ps).
- Called from
- Call to
- subroutine presprofileoperators_mod/ppo_vertlayerssetup(operatortype, pressinput, numinputlevs)¶
- Purpose
Preliminary calculations for producing components required for vertical integration (or averaging) w.r.t. pressure for the full vertical rangeor a set of target layers. To be called before routine ppo_vertIntegWgts or ppo_vertAvgWgts.
Integration calculations are performed appling quadratic interpolation in P between level.
- Input
- operatorType
‘integ’ for intergration; ‘avg’ for averaging
- pressInput
Reference input levels
- numInputLevs
# of model vertical levels
- Output
- boundaries(numInputLevs+1)
Input layer boundaries assuming provided input levels can be taken as mid-layer values.
- weights
Second order Lagrangian interp integration weights or unity for averaging weights
- Comments
This subroutine does the following:
Setting of layer boundaries
If integration, determining integration weights associated to second order Lagrangian interpolation. Otherwise, initialize weights to unity.
Layer boundaries are taken as mid-point between provided levels in lnP coordinate. Layer values are set to be the values interpolated to the mid-point in P within the various layers. Interpolation in P is done quadratically.
- Arguments
operatortype [character ,in] :: ‘integ’ for integration; ‘avg’ for averaging
pressinput (numinputlevs) [real ,in] :: Reference input levels
numinputlevs [integer ,in,] :: # of model vertical levels
- subroutine presprofileoperators_mod/ppo_vertintegwgts(targetlayerstop, targetlayersbot, numinputlevs, numtargetlevs, kstart, kend, wgts[, wgts_opt[, skiptype_opt[, outbound_opt[, success_opt[, dealloc_opt]]]]])¶
- Purpose
To calculate integration weights “wgts” required for vertical integration w.r.t. pressure for the full vertical range or a set of target layers. Given the calculated weights and a user intergrand array vector X, the integral for a given layer i would be given by sum(wgts(i,:)*X(:))
Integration calculations are performed applying quadratic interpolation in P between level.
Routine ppo_vertLayersSetup to be called beforehand to generate Lagrangian weights and related layer boundaries (arrays ‘weights’ and ‘boundaries’)
- Input
- targetLayersTop
top of target layers
- targetLayersBot
bottom of target layers
- numInputLevs
# of original/input vertical levels
- numTargetLevs
# of target vertical levels
- Arguments
kstart (numtargetlevs) [integer ,inout] :: Index of first relevant original/input level for each target level
kend (numtargetlevs) [integer ,inout] ::
- Index of last relevant original/input level for each target level
If kstart and kend are non-zero on input, the input are initial estimates of the values.
- weights
See routine ppo_vertLayersSetup
- boundaries
Boundaries of input layers
- skipType_opt
Skipping processing of specific target layers depending on case: ‘default’ - skipping application via input success_opt only ‘doAll&noExtrap’ - application of both success_opt and outbound_opt
outbound_opt (numtargetlevs) [integer ,inout,] :: Flag indicating if obs outside input vertical range (0 for no)
success_opt (numtargetlevs) [logical ,inout,] :: success of interpolation
wgts (numtargetlevs,numinputlevs) [real ,out] :: Averaging weights
wgts_opt (numtargetlevs,numinputlevs) [real ,out,] :: Part of averaging weights not related to resolution
targetlayerstop (numtargetlevs) [real ,in] :: top of target layers
targetlayersbot (numtargetlevs) [real ,in] :: bottom of target layers
numinputlevs [integer ,in] :: # of original/input vertical levels
numtargetlevs [integer ,in,] :: # of target vertical levels
- Options
dealloc_opt [logical ,in,] :: Logical indicating if deallocation is desired when done
skiptype_opt [character ,in,] :: Skipping processing of specific target layers depending on case
- Output
- Call to
- function presprofileoperators_mod/ppo_getlevelindex(level, layerboundarylevels, topbtm, numboundaries)¶
- Purpose
To get the vertical input level index for level within target layer and nearest specified layer boundary.
- Arguments
level [real ,in] :: Target layer index
layerboundarylevels (numboundaries) [real ,in] :: Layer boundaries
topbtm [character ,in] :: indicating whether we are looking for top or bottom level
numboundaries [integer ,in,] :: Number of layer boundaries
- Return
ppo_getlevelindex [integer ]
- Called from
- subroutine presprofileoperators_mod/ppo_vertavgwgts(targetlayerstop, targetlayersbot, numinputlevs, numtargetlevs, kstart, kend, wgts[, wgts_opt[, skiptype_opt[, outbound_opt[, success_opt[, dealloc_opt]]]]])¶
- Purpose
To calculate averaging weights “wgts” required for vertical averaging w.r.t. ln(pressure) for the full vertical range or a set of target layers. Given the calculated weights and a user input array vector X, the average for a given layer i would be given by sum(wgts(i,:)*X(:))
Routine ppo_vertLayersSetup to be called beforehand to initial weigths and related layer boundaries (arrays ‘weights’ and ‘boundaries’)
- Input
- targetLayersTop
top of target layers
- targetLayersBot
bottom of target layers
- numInputLevs
# of original/input vertical levels
- numTargetLevs
# of target vertical levels
- Arguments
kstart (numtargetlevs) [integer ,inout] :: Index of first relevant original/input level for each target level
kend (numtargetlevs) [integer ,inout] ::
- Index of last relevant original/input level for each target level
If kstart and kend are non-zero on input, the input are initial estimates of the values.
- weights
See routine ppo_vertLayersSetup
- boundaries
Boundaries of input layers
- skipType_opt
Skipping processing of specific target layers depending on case: ‘default’ - skipping application via input success_opt only ‘doAll&noExtrap’ - application of both success_opt and outbound_opt
outbound_opt (numtargetlevs) [integer ,inout,] :: Flag indicating if obs outside input vertical range (0 for no)
success_opt (numtargetlevs) [logical ,inout,] :: success of interpolation
wgts (numtargetlevs,numinputlevs) [real ,out] :: Averaging weights
wgts_opt (numtargetlevs,numinputlevs) [real ,out,] :: Part of averaging weights not related to resolution
targetlayerstop (numtargetlevs) [real ,in] :: top of target layers
targetlayersbot (numtargetlevs) [real ,in] :: bottom of target layers
numinputlevs [integer ,in] :: # of original/input vertical levels
numtargetlevs [integer ,in,] :: # of target vertical levels
- Options
dealloc_opt [logical ,in,] :: Logical indicating if deallocation is desired when done
skiptype_opt [character ,in,] :: Skipping processing of specific target layers depending on case
- Output
- Call to