FV3 Bundle
Hyperbolic_Step.f90
Go to the documentation of this file.
1 !
2 ! Hyperbolic step functions for differentiable replacement of IF statements
3 !
4 !
5 ! CREATION HISTORY:
6 ! Written by: Paul van Delst, 09-Nov-2010
7 ! paul.vandelst@noaa.gov
8 !
9 
11 
12  ! -----------------
13  ! Environment setup
14  ! -----------------
15  ! Module use
16  USE type_kinds, ONLY: fp
17  ! Disable implicit typing
18  IMPLICIT NONE
19 
20 
21  ! ------------
22  ! Visibilities
23  ! ------------
24  PRIVATE
25  PUBLIC :: step
26  PUBLIC :: step_tl
27  PUBLIC :: step_ad
28 
29 
30  ! -----------------
31  ! Module parameters
32  ! -----------------
33  CHARACTER(*), PARAMETER :: module_version_id = &
34  '$Id: Hyperbolic_Step.f90 60152 2015-08-13 19:19:13Z paul.vandelst@noaa.gov $'
35  ! Literals
36  REAL(fp), PARAMETER :: zero = 0.0_fp
37  REAL(fp), PARAMETER :: point5 = 0.5_fp
38  REAL(fp), PARAMETER :: one = 1.0_fp
39  ! X-input maximum value
40  REAL(fp), PARAMETER :: xcutoff = 70.0_fp
41 
42 CONTAINS
43 
44 
45 !--------------------------------------------------------------------------------
46 !:sdoc+:
47 !
48 ! NAME:
49 ! Step
50 !
51 ! PURPOSE:
52 ! Subroutine to compute a hyperbolic, differentiable, step function:
53 !
54 ! g(x) = 0.5(1 + TANH(x))
55 !
56 ! NOTE: No input checking of the validity of the x-argument for use
57 ! with TANH() is done.
58 !
59 ! CALLING SEQUENCE:
60 ! CALL Step( x, g )
61 !
62 !
63 ! INPUTS:
64 ! x: The function abscissa.
65 ! UNITS: N/A
66 ! TYPE: REAL(fp)
67 ! DIMENSION: Scalar
68 ! ATTRIBUTES: INTENT(IN)
69 !
70 ! OUTPUTS:
71 ! g: The hyperbolic step function value.
72 ! UNITS: N/A
73 ! TYPE: REAL(fp)
74 ! DIMENSION: Scalar
75 ! ATTRIBUTES: INTENT(OUT)
76 !
77 !:sdoc-:
78 !--------------------------------------------------------------------------------
79 
80  SUBROUTINE step( x, g )
81  REAL(fp), INTENT(IN) :: x
82  REAL(fp), INTENT(OUT) :: g
83  g = point5 * ( one + tanh(x) )
84  END SUBROUTINE step
85 
86 
87 !--------------------------------------------------------------------------------
88 !:sdoc+:
89 !
90 ! NAME:
91 ! Step_TL
92 !
93 ! PURPOSE:
94 ! Subroutine to compute the tangent-linear form of a hyperbolic,
95 ! differentiable, step function:
96 !
97 ! g(x) = 0.5(1 + TANH(x))
98 !
99 ! NOTE: Computations are only performed for input |x| < 70 to avoid
100 ! infinite result for COSH().
101 !
102 ! CALLING SEQUENCE:
103 ! CALL Step_TL( x, x_TL, g_TL )
104 !
105 !
106 ! INPUTS:
107 ! x: The function abscissa.
108 ! UNITS: N/A
109 ! TYPE: REAL(fp)
110 ! DIMENSION: Scalar
111 ! ATTRIBUTES: INTENT(IN)
112 !
113 ! x_TL: The tangent-linear abscissa.
114 ! UNITS: N/A
115 ! TYPE: REAL(fp)
116 ! DIMENSION: Scalar
117 ! ATTRIBUTES: INTENT(IN)
118 !
119 ! OUTPUTS:
120 ! g_TL: The tangent-linear hyperbolic step function value.
121 ! UNITS: N/A
122 ! TYPE: REAL(fp)
123 ! DIMENSION: Scalar
124 ! ATTRIBUTES: INTENT(OUT)
125 !
126 !:sdoc-:
127 !--------------------------------------------------------------------------------
128 
129  SUBROUTINE step_tl( x, x_TL, g_TL )
130  REAL(fp), INTENT(IN) :: x, x_tl
131  REAL(fp), INTENT(OUT) :: g_tl
132  IF ( abs(x) < xcutoff ) THEN
133  g_tl = point5 * x_tl / cosh(x)**2
134  ELSE
135  g_tl = zero
136  END IF
137  END SUBROUTINE step_tl
138 
139 
140 !--------------------------------------------------------------------------------
141 !:sdoc+:
142 !
143 ! NAME:
144 ! Step_AD
145 !
146 ! PURPOSE:
147 ! Subroutine to compute the adjoint of a hyperbolic, differentiable,
148 ! step function:
149 !
150 ! g(x) = 0.5(1 + TANH(x))
151 !
152 ! NOTE: Computations are only performed for input |x| < 70 to avoid
153 ! infinite result for COSH().
154 !
155 ! CALLING SEQUENCE:
156 ! CALL Step_AD( x, g_AD, x_AD )
157 !
158 !
159 ! INPUTS:
160 ! x: The function abscissa.
161 ! UNITS: N/A
162 ! TYPE: REAL(fp)
163 ! DIMENSION: Scalar
164 ! ATTRIBUTES: INTENT(IN)
165 !
166 ! g_AD: The adjoint hyperbolic step function value.
167 ! NOTE: *** SET TO ZERO UPON EXIT ***
168 ! UNITS: N/A
169 ! TYPE: REAL(fp)
170 ! DIMENSION: Scalar
171 ! ATTRIBUTES: INTENT(IN OUT)
172 !
173 ! OUTPUTS:
174 ! x_AD: The adjoint abscissa.
175 ! NOTE: *** MUST CONTAIN VALUE UPON ENTRY ***
176 ! UNITS: N/A
177 ! TYPE: REAL(fp)
178 ! DIMENSION: Scalar
179 ! ATTRIBUTES: INTENT(IN OUT)
180 !
181 !:sdoc-:
182 !--------------------------------------------------------------------------------
183 
184  SUBROUTINE step_ad( x, g_AD, x_AD )
185  REAL(fp), INTENT(IN) :: x
186  REAL(fp), INTENT(IN OUT) :: g_ad ! AD Input
187  REAL(fp), INTENT(IN OUT) :: x_ad ! AD Output
188  IF ( abs(x) < xcutoff ) THEN
189  x_ad = x_ad + point5 * g_ad / cosh(x)**2
190  END IF
191  g_ad = zero
192  END SUBROUTINE step_ad
193 
194 END MODULE hyperbolic_step
real(fp), parameter xcutoff
real(fp), parameter, public zero
real(fp), parameter point5
integer, parameter, public fp
Definition: Type_Kinds.f90:124
subroutine, public step_ad(x, g_AD, x_AD)
character(*), parameter module_version_id
real(fp), parameter, public one
subroutine, public step(x, g)
subroutine, public step_tl(x, x_TL, g_TL)