6 implicit none ;
private 8 public plm_boundary_extrapolation
9 public plm_extrapolate_slope
10 public plm_monotonized_slope
11 public plm_reconstruction
15 real,
parameter :: hneglect_dflt = 1.e-30
21 real elemental pure function plm_slope_wa(h_l, h_c, h_r, h_neglect, u_l, u_c, u_r)
22 real,
intent(in) :: h_l
23 real,
intent(in) :: h_c
24 real,
intent(in) :: h_r
25 real,
intent(in) :: h_neglect
26 real,
intent(in) :: u_l
27 real,
intent(in) :: u_c
28 real,
intent(in) :: u_r
30 real :: sigma_l, sigma_c, sigma_r
39 sigma_c = 2.0 * ( u_r - u_l ) * ( h_c / ( h_l + 2.0*h_c + h_r + h_neglect) )
42 u_min = min( u_l, u_c, u_r )
43 u_max = max( u_l, u_c, u_r )
44 if ( (sigma_l * sigma_r) > 0.0 )
then 47 plm_slope_wa = sign( min( abs(sigma_c), 2.*min( u_c - u_min, u_max - u_c ) ), sigma_c )
55 if (u_c - 0.5*abs(plm_slope_wa) < u_min .or. u_c + 0.5*abs(plm_slope_wa) > u_max)
then 56 plm_slope_wa = plm_slope_wa * ( 1. - epsilon(plm_slope_wa) )
62 if (abs(plm_slope_wa) < 1.e-140) plm_slope_wa = 0.
64 end function plm_slope_wa
67 real elemental pure function plm_slope_cw(h_l, h_c, h_r, h_neglect, u_l, u_c, u_r)
68 real,
intent(in) :: h_l
69 real,
intent(in) :: h_c
70 real,
intent(in) :: h_r
71 real,
intent(in) :: h_neglect
72 real,
intent(in) :: u_l
73 real,
intent(in) :: u_c
74 real,
intent(in) :: u_r
76 real :: sigma_l, sigma_c, sigma_r
81 h_cn = h_c + h_neglect
91 sigma_c = ( h_c / ( h_cn + ( h_l + h_r ) ) ) * ( &
92 ( 2.*h_l + h_c ) / ( h_r + h_cn ) * sigma_r &
93 + ( 2.*h_r + h_c ) / ( h_l + h_cn ) * sigma_l )
96 u_min = min( u_l, u_c, u_r )
97 u_max = max( u_l, u_c, u_r )
98 if ( (sigma_l * sigma_r) > 0.0 )
then 101 plm_slope_cw = sign( min( abs(sigma_c), 2.*min( u_c - u_min, u_max - u_c ) ), sigma_c )
109 if (u_c - 0.5*abs(plm_slope_cw) < u_min .or. u_c + 0.5*abs(plm_slope_cw) > u_max)
then 110 plm_slope_cw = plm_slope_cw * ( 1. - epsilon(plm_slope_cw) )
116 if (abs(plm_slope_cw) < 1.e-140) plm_slope_cw = 0.
118 end function plm_slope_cw
121 real elemental pure function plm_monotonized_slope(u_l, u_c, u_r, s_l, s_c, s_r)
122 real,
intent(in) :: u_l
123 real,
intent(in) :: u_c
124 real,
intent(in) :: u_r
125 real,
intent(in) :: s_l
126 real,
intent(in) :: s_c
127 real,
intent(in) :: s_r
129 real :: e_r, e_l, edge
133 almost_two = 2. * ( 1. - epsilon(s_c) )
141 edge = u_c - 0.5 * s_c
142 if ( ( edge - e_r ) * ( u_c - edge ) < 0. )
then 143 edge = 0.5 * ( edge + e_r )
144 slp = min( slp, abs( edge - u_c ) * almost_two )
148 edge = u_c + 0.5 * s_c
149 if ( ( edge - u_c ) * ( e_l - edge ) < 0. )
then 150 edge = 0.5 * ( edge + e_l )
151 slp = min( slp, abs( edge - u_c ) * almost_two )
154 plm_monotonized_slope = sign( slp, s_c )
156 end function plm_monotonized_slope
160 real elemental pure function plm_extrapolate_slope(h_l, h_c, h_neglect, u_l, u_c)
161 real,
intent(in) :: h_l
162 real,
intent(in) :: h_c
163 real,
intent(in) :: h_neglect
164 real,
intent(in) :: u_l
165 real,
intent(in) :: u_c
175 left_edge = (u_l*hc + u_c*hl) / (hl + hc)
177 plm_extrapolate_slope = 2.0 * ( u_c - left_edge )
179 end function plm_extrapolate_slope
186 subroutine plm_reconstruction( N, h, u, edge_values, ppoly_coef, h_neglect )
187 integer,
intent(in) :: n
188 real,
dimension(:),
intent(in) :: h
189 real,
dimension(:),
intent(in) :: u
190 real,
dimension(:,:),
intent(inout) :: edge_values
192 real,
dimension(:,:),
intent(inout) :: ppoly_coef
194 real,
optional,
intent(in) :: h_neglect
200 real :: u_l, u_c, u_r
201 real :: h_l, h_c, h_r, h_cn
204 real :: u_min, u_max, e_l, e_r, edge
206 real,
dimension(N) :: slp, mslp
209 hneglect = hneglect_dflt ;
if (
present(h_neglect)) hneglect = h_neglect
211 almost_one = 1. - epsilon(slope)
215 slp(k) = plm_slope_wa(h(k-1), h(k), h(k+1), hneglect, u(k-1), u(k), u(k+1))
224 mslp(k) = plm_monotonized_slope( u(k-1), u(k), u(k+1), slp(k-1), slp(k), slp(k+1) )
230 edge_values(1,1) = u(1)
231 edge_values(1,2) = u(1)
232 ppoly_coef(1,1) = u(1)
236 u_l = u(k) - 0.5 * slope
237 u_r = u(k) + 0.5 * slope
239 edge_values(k,1) = u_l
240 edge_values(k,2) = u_r
241 ppoly_coef(k,1) = u_l
242 ppoly_coef(k,2) = ( u_r - u_l )
245 edge = ppoly_coef(k,2) + ppoly_coef(k,1)
246 e_r = u(k+1) - 0.5 * sign( mslp(k+1), slp(k+1) )
247 if ( (edge-u(k))*(e_r-edge)<0.)
then 248 ppoly_coef(k,2) = ppoly_coef(k,2) * almost_one
251 edge_values(n,1) = u(n)
252 edge_values(n,2) = u(n)
253 ppoly_coef(n,1) = u(n)
256 end subroutine plm_reconstruction
268 subroutine plm_boundary_extrapolation( N, h, u, edge_values, ppoly_coef, h_neglect )
269 integer,
intent(in) :: n
270 real,
dimension(:),
intent(in) :: h
271 real,
dimension(:),
intent(in) :: u
272 real,
dimension(:,:),
intent(inout) :: edge_values
274 real,
dimension(:,:),
intent(inout) :: ppoly_coef
276 real,
optional,
intent(in) :: h_neglect
283 hneglect = hneglect_dflt ;
if (
present(h_neglect)) hneglect = h_neglect
286 slope = - plm_extrapolate_slope( h(2), h(1), hneglect, u(2), u(1) )
288 edge_values(1,1) = u(1) - 0.5 * slope
289 edge_values(1,2) = u(1) + 0.5 * slope
291 ppoly_coef(1,1) = edge_values(1,1)
292 ppoly_coef(1,2) = edge_values(1,2) - edge_values(1,1)
295 slope = plm_extrapolate_slope( h(n-1), h(n), hneglect, u(n-1), u(n) )
297 edge_values(n,1) = u(n) - 0.5 * slope
298 edge_values(n,2) = u(n) + 0.5 * slope
300 ppoly_coef(n,1) = edge_values(n,1)
301 ppoly_coef(n,2) = edge_values(n,2) - edge_values(n,1)
303 end subroutine plm_boundary_extrapolation
Piecewise linear reconstruction functions.