MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
SmoothingFunctions.f90
Go to the documentation of this file.
2  use kindmodule, only: dp, i4b
3  use constantsmodule, only: dzero, dhalf, done, dtwo, dthree, dfour, &
5  implicit none
6 
7 contains
8 
9  !> @ brief SCurve
10  !!
11  !! Computes the S curve for smooth derivatives between x=0 and x=1
12  !! from mfusg smooth subroutine in gwf2wel7u1.f
13  !<
14  subroutine sscurve(x, range, dydx, y)
15  real(DP), intent(in) :: x
16  real(DP), intent(in) :: range
17  real(DP), intent(inout) :: dydx
18  real(DP), intent(inout) :: y
19  !--local variables
20  real(DP) :: s
21  real(DP) :: xs
22  ! -- code
23  !
24  s = range
25  if (s < dprec) s = dprec
26  xs = x / s
27  if (xs < dzero) xs = dzero
28  if (xs <= dzero) then
29  y = dzero
30  dydx = dzero
31  elseif (xs < done) then
32  y = -dtwo * xs**dthree + dthree * xs**dtwo
33  dydx = -dsix * xs**dtwo + dsix * xs
34  else
35  y = done
36  dydx = dzero
37  end if
38  end subroutine sscurve
39 
40  !> @ brief sCubicLinear
41  !!
42  !! Computes the s curve where dy/dx = 0 at x=0; and dy/dx = 1 at x=1.
43  !! Smooths from zero to a slope of 1.
44  !<
45  subroutine scubiclinear(x, range, dydx, y)
46  real(DP), intent(in) :: x
47  real(DP), intent(in) :: range
48  real(DP), intent(inout) :: dydx
49  real(DP), intent(inout) :: y
50  !--local variables
51  real(DP) :: s
52  real(DP) :: xs
53  ! -- code
54  !
55  s = range
56  if (s < dprec) s = dprec
57  xs = x / s
58  if (xs < dzero) xs = dzero
59  if (xs <= dzero) then
60  y = dzero
61  dydx = dzero
62  elseif (xs < done) then
63  y = -done * xs**dthree + dtwo * xs**dtwo
64  dydx = -dthree * xs**dtwo + dfour * xs
65  else
66  y = done
67  dydx = dzero
68  end if
69  end subroutine scubiclinear
70 
71  !> @ brief sRamp
72  !!
73  !! Smoothed ramp function; a smooth approximation of max(x, 0) with a
74  !! continuous value and slope. The value is zero with zero slope for x <= 0 and
75  !! is the exact line x with unit slope for x >= range, joined by a cubic over
76  !! (0, range). Unlike sCubicLinear, which levels off at 1, the value continues
77  !! with unit slope, so it is exact outside the transition (max(x, 0) for
78  !! |x| >= range).
79  !<
80  subroutine sramp(x, range, dydx, y)
81  real(DP), intent(in) :: x
82  real(DP), intent(in) :: range
83  real(DP), intent(inout) :: dydx
84  real(DP), intent(inout) :: y
85  !--local variables
86  real(DP) :: s
87  real(DP) :: xs
88  ! -- code
89  !
90  s = range
91  if (s < dprec) s = dprec
92  xs = x / s
93  if (xs <= dzero) then
94  y = dzero
95  dydx = dzero
96  elseif (xs < done) then
97  y = x * xs * (dtwo - xs)
98  dydx = xs * (dfour - dthree * xs)
99  else
100  y = x
101  dydx = done
102  end if
103  end subroutine sramp
104 
105  !> @ brief sCubic
106  !!
107  !! Nonlinear smoothing function returns value between 0-1; cubic function
108  !<
109  subroutine scubic(x, range, dydx, y)
110  real(DP), intent(inout) :: x
111  real(DP), intent(inout) :: range
112  real(DP), intent(inout) :: dydx
113  real(DP), intent(inout) :: y
114  !--local variables
115  real(DP) :: s, aa, bb
116  real(DP) :: cof1, cof2, cof3
117  ! -- code
118  !
119  dydx = dzero
120  y = dzero
121  if (range < dprec) range = dprec
122  if (x < dprec) x = dprec
123  s = range
124  aa = -dsix / (s**dthree)
125  bb = -dsix / (s**dtwo)
126  cof1 = x**dtwo
127  cof2 = -(dtwo * x) / (s**dthree)
128  cof3 = dthree / (s**dtwo)
129  y = cof1 * (cof2 + cof3)
130  dydx = (aa * x**dtwo - bb * x)
131  if (x <= dzero) then
132  y = dzero
133  dydx = dzero
134  else if ((x - s) > -dprec) then
135  y = done
136  dydx = dzero
137  end if
138  end subroutine scubic
139 
140  !> @ brief sLinear
141  !!
142  !! Linear smoothing function returns value between 0-1
143  !<
144  subroutine slinear(x, range, dydx, y)
145  real(DP), intent(inout) :: x
146  real(DP), intent(inout) :: range
147  real(DP), intent(inout) :: dydx
148  real(DP), intent(inout) :: y
149  !--local variables
150  real(DP) :: s
151  ! -- code
152  !
153  dydx = dzero
154  y = dzero
155  if (range < dprec) range = dprec
156  if (x < dprec) x = dprec
157  s = range
158  y = done - (s - x) / s
159  dydx = done / s
160  if (y > done) then
161  y = done
162  dydx = dzero
163  end if
164  end subroutine slinear
165 
166  !> @ brief sQuadratic
167  !!
168  !! Nonlinear quadratic smoothing function returns value between 0-1
169  !<
170  subroutine squadratic(x, range, dydx, y)
171  real(DP), intent(inout) :: x
172  real(DP), intent(inout) :: range
173  real(DP), intent(inout) :: dydx
174  real(DP), intent(inout) :: y
175  !--local variables
176  real(DP) :: s
177  ! -- code
178  !
179  dydx = dzero
180  y = dzero
181  if (range < dprec) range = dprec
182  if (x < dprec) x = dprec
183  s = range
184  y = (x**dtwo) / (s**dtwo)
185  dydx = dtwo * x / (s**dtwo)
186  if (y > done) then
187  y = done
188  dydx = dzero
189  end if
190  end subroutine squadratic
191 
192  !> @ brief sChSmooth
193  !!
194  !! Function to smooth channel variables during channel drying
195  !<
196  subroutine schsmooth(d, smooth, dwdh)
197  real(DP), intent(in) :: d
198  real(DP), intent(inout) :: smooth
199  real(DP), intent(inout) :: dwdh
200  !
201  ! -- local variables
202  real(DP) :: s
203  real(DP) :: diff
204  real(DP) :: aa
205  real(DP) :: ad
206  real(DP) :: b
207  real(DP) :: x
208  real(DP) :: y
209  ! -- code
210  !
211  smooth = dzero
212  s = dem5
213  x = d
214  diff = x - s
215  if (diff > dzero) then
216  smooth = done
217  dwdh = dzero
218  else
219  aa = -done / (s**dtwo)
220  ad = -dtwo / (s**dtwo)
221  b = dtwo / s
222  y = aa * x**dtwo + b * x
223  dwdh = (ad * x + b)
224  if (x <= dzero) then
225  y = dzero
226  dwdh = dzero
227  else if (diff > -dem14) then
228  y = done
229  dwdh = dzero
230  end if
231  smooth = y
232  end if
233  end subroutine schsmooth
234 
235  !> @ brief sLinearSaturation
236  !!
237  !! Linear saturation function returns value between 0-1
238  !<
239  function slinearsaturation(top, bot, x) result(y)
240  ! -- return
241  real(dp) :: y
242  ! -- dummy variables
243  real(dp), intent(in) :: top
244  real(dp), intent(in) :: bot
245  real(dp), intent(in) :: x
246  ! -- local
247  real(dp) :: b
248  ! -- code
249  !
250  b = top - bot
251  if (x < bot) then
252  y = dzero
253  else if (x > top) then
254  y = done
255  else
256  y = (x - bot) / b
257  end if
258  end function slinearsaturation
259 
260  !> @ brief sCubicSaturation
261  !!
262  !! Nonlinear cubic saturation function returns value between 0-1
263  !<
264  function scubicsaturation(top, bot, x, eps) result(y)
265  ! -- return
266  real(dp) :: y
267  ! -- dummy variables
268  real(dp), intent(in) :: top
269  real(dp), intent(in) :: bot
270  real(dp), intent(in) :: x
271  real(dp), intent(in), optional :: eps
272  ! -- local
273  real(dp) :: teps
274  real(dp) :: w
275  real(dp) :: b
276  real(dp) :: s
277  real(dp) :: cof1
278  real(dp) :: cof2
279  ! -- code
280  !
281  if (present(eps)) then
282  teps = eps
283  else
284  teps = dem2
285  end if
286  w = x - bot
287  b = top - bot
288  s = teps * b
289  cof1 = done / (s**dtwo)
290  cof2 = dtwo / s
291  if (w < dzero) then
292  y = dzero
293  else if (w < s) then
294  y = -cof1 * (w**dthree) + cof2 * (w**dtwo)
295  else if (w < (b - s)) then
296  y = w / b
297  else if (w < b) then
298  y = done + cof1 * ((b - w)**dthree) - cof2 * ((b - w)**dtwo)
299  else
300  y = done
301  end if
302 
303  end function scubicsaturation
304 
305  !> @ brief sQuadraticSaturation
306  !!
307  !! Nonlinear quadratic saturation function returns value between 0-1
308  !<
309  function squadraticsaturation(top, bot, x, eps) result(y)
310  ! -- return
311  real(dp) :: y
312  ! -- dummy variables
313  real(dp), intent(in) :: top
314  real(dp), intent(in) :: bot
315  real(dp), intent(in) :: x
316  real(dp), optional, intent(in) :: eps
317  ! -- local
318  real(dp) :: teps
319  real(dp) :: b
320  real(dp) :: br
321  real(dp) :: bri
322  real(dp) :: av
323  ! -- code
324  !
325  if (present(eps)) then
326  teps = eps
327  else
328  teps = dem6
329  end if
330  b = top - bot
331  if (b > dzero) then
332  if (x < bot) then
333  br = dzero
334  else if (x > top) then
335  br = done
336  else
337  br = (x - bot) / b
338  end if
339  av = done / (done - teps)
340  bri = done - br
341  if (br < teps) then
342  y = av * dhalf * (br * br) / teps
343  elseif (br < (done - teps)) then
344  y = av * br + dhalf * (done - av)
345  elseif (br < done) then
346  y = done - ((av * dhalf * (bri * bri)) / teps)
347  else
348  y = done
349  end if
350  else
351  if (x < bot) then
352  y = dzero
353  else
354  y = done
355  end if
356  end if
357 
358  end function squadraticsaturation
359 
360  !> @ brief sQuadraticSaturation
361  !!
362  !! van Genuchten saturation function returns value between 0-1
363  !<
364  function svangenuchtensaturation(top, bot, x, alpha, beta, sr) result(y)
365  ! -- return
366  real(dp) :: y
367  ! -- dummy variables
368  real(dp), intent(in) :: top
369  real(dp), intent(in) :: bot
370  real(dp), intent(in) :: x
371  real(dp), intent(in) :: alpha
372  real(dp), intent(in) :: beta
373  real(dp), intent(in) :: sr
374  ! -- local
375  real(dp) :: b
376  real(dp) :: pc
377  real(dp) :: gamma
378  real(dp) :: seff
379  ! -- code
380  !
381  b = top - bot
382  pc = (dhalf * b) - x
383  if (pc <= dzero) then
384  y = dzero
385  else
386  gamma = done - (done / beta)
387  seff = (done + (alpha * pc)**beta)**gamma
388  seff = done / seff
389  y = seff * (done - sr) + sr
390  end if
391 
392  end function svangenuchtensaturation
393 
394  !> @ brief Derivative of the quadratic saturation function
395  !!
396  !! Derivative of nonlinear smoothing function returns value between 0-1;
397  !<
398  function squadraticsaturationderivative(top, bot, x, eps) result(y)
399  ! -- return
400  real(dp) :: y
401  ! -- dummy variables
402  real(dp), intent(in) :: top
403  real(dp), intent(in) :: bot
404  real(dp), intent(in) :: x
405  real(dp), optional, intent(in) :: eps
406  ! -- local
407  real(dp) :: teps
408  real(dp) :: b
409  real(dp) :: br
410  real(dp) :: bri
411  real(dp) :: av
412  ! -- code
413  !
414  if (present(eps)) then
415  teps = eps
416  else
417  teps = dem6
418  end if
419  b = top - bot
420  if (x < bot) then
421  br = dzero
422  else if (x > top) then
423  br = done
424  else
425  br = (x - bot) / b
426  end if
427  av = done / (done - teps)
428  bri = done - br
429  if (br < teps) then
430  y = av * br / teps
431  elseif (br < (done - teps)) then
432  y = av
433  elseif (br < done) then
434  y = av * bri / teps
435  else
436  y = dzero
437  end if
438  y = y / b
439 
440  end function squadraticsaturationderivative
441 
442  !> @ brief sQSaturation
443  !!
444  !! Nonlinear smoothing function returns value between 0-1
445  !<
446  function sqsaturation(top, bot, x, c1, c2) result(y)
447  ! -- return
448  real(dp) :: y
449  ! -- dummy variables
450  real(dp), intent(in) :: top
451  real(dp), intent(in) :: bot
452  real(dp), intent(in) :: x
453  real(dp), intent(in), optional :: c1
454  real(dp), intent(in), optional :: c2
455  ! -- local
456  real(dp) :: w
457  real(dp) :: b
458  real(dp) :: s
459  real(dp) :: cof1
460  real(dp) :: cof2
461  ! -- code
462  !
463  ! -- process optional variables
464  if (present(c1)) then
465  cof1 = c1
466  else
467  cof1 = -dtwo
468  end if
469  if (present(c2)) then
470  cof2 = c2
471  else
472  cof2 = dthree
473  end if
474  !
475  ! -- calculate head difference from bottom (w),
476  ! calculate range (b), and
477  ! calculate normalized head difference from bottom (s)
478  w = x - bot
479  b = top - bot
480  s = w / b
481  !
482  ! -- divide cof1 and cof2 by range to the power 3 and 2, respectively
483  cof1 = cof1 / b**dthree
484  cof2 = cof2 / b**dtwo
485  !
486  ! -- calculate fraction
487  if (s < dzero) then
488  y = dzero
489  else if (s < done) then
490  y = cof1 * w**dthree + cof2 * w**dtwo
491  else
492  y = done
493  end if
494  end function sqsaturation
495 
496  !> @ brief sQSaturationDerivative
497  !!
498  !! Nonlinear smoothing function returns value between 0-1
499  !<
500  function sqsaturationderivative(top, bot, x, c1, c2) result(y)
501  ! -- return
502  real(dp) :: y
503  ! -- dummy variables
504  real(dp), intent(in) :: top
505  real(dp), intent(in) :: bot
506  real(dp), intent(in) :: x
507  real(dp), intent(in), optional :: c1
508  real(dp), intent(in), optional :: c2
509  ! -- local
510  real(dp) :: w
511  real(dp) :: b
512  real(dp) :: s
513  real(dp) :: cof1
514  real(dp) :: cof2
515  ! -- code
516  !
517  !
518  ! -- process optional variables
519  if (present(c1)) then
520  cof1 = c1
521  else
522  cof1 = -dtwo
523  end if
524  if (present(c2)) then
525  cof2 = c2
526  else
527  cof2 = dthree
528  end if
529  !
530  ! -- calculate head difference from bottom (w),
531  ! calculate range (b), and
532  ! calculate normalized head difference from bottom (s)
533  w = x - bot
534  b = top - bot
535  s = w / b
536  !
537  ! -- multiply cof1 and cof2 by 3 and 2, respectively, and then
538  ! divide by range to the power 3 and 2, respectively
539  cof1 = cof1 * dthree / b**dthree
540  cof2 = cof2 * dtwo / b**dtwo
541  !
542  ! -- calculate derivative of fraction with respect to x
543  if (s < dzero) then
544  y = dzero
545  else if (s < done) then
546  y = cof1 * w**dtwo + cof2 * w
547  else
548  y = dzero
549  end if
550  end function sqsaturationderivative
551 
552  !> @ brief sSlope
553  !!
554  !! Nonlinear smoothing function returns a smoothed value of y whose limbs are
555  !! the lines yi + (sm * dx) for x-values less than xi and yi + (sp * dx) for
556  !! x-values greater than xi, where dx = x - xi. The slope change at xi is
557  !! smoothed with the hyperbolic smoothed min and max of Chen and Mangasarian
558  !! (1996), as applied to hydrologic-model thresholds by Kavetski and Kuczera
559  !! (2007, eq. 18; https://dx.doi.org/10.1029/2006WR005195); here the smoothing
560  !! constant is b**2 - a**2 with b = a / (sqrt(2) - 1). Currently unused.
561  !<
562  function sslope(x, xi, yi, sm, sp, ta) result(y)
563  ! -- return
564  real(dp) :: y
565  ! -- dummy variables
566  real(dp), intent(in) :: x
567  real(dp), intent(in) :: xi
568  real(dp), intent(in) :: yi
569  real(dp), intent(in) :: sm
570  real(dp), intent(in) :: sp
571  real(dp), optional, intent(in) :: ta
572  ! -- local
573  real(dp) :: a
574  real(dp) :: b
575  real(dp) :: dx
576  real(dp) :: xm
577  real(dp) :: xp
578  real(dp) :: ym
579  real(dp) :: yp
580  !
581  ! -- set smoothing variable a
582  if (present(ta)) then
583  a = ta
584  else
585  a = dem8
586  end if
587  !
588  ! -- calculate b from smoothing variable a
589  b = a / (sqrt(dtwo) - done)
590  !
591  ! -- calculate contributions to y. xm and xp are smoothed values of
592  ! min(x, xi) and max(x, xi), so the limbs are yi + sm*dx (x < xi) and
593  ! yi + sp*dx (x > xi).
594  dx = x - xi
595  xm = dhalf * (x + xi - sqrt(dx**dtwo + b**dtwo - a**dtwo))
596  xp = dhalf * (x + xi + sqrt(dx**dtwo + b**dtwo - a**dtwo))
597  ym = sm * (xm - xi)
598  yp = sp * (xp - xi)
599  !
600  ! -- calculate y from ym and yp contributions
601  y = yi + ym + yp
602  end function sslope
603 
604  !> @ brief sSlopeDerivative
605  !!
606  !! Derivative of sSlope (see that routine for the provenance): smoothly
607  !! transitions from slope sm for x-values less than xi to slope sp for x-values
608  !! greater than xi, where dx = x - xi.
609  !<
610  function sslopederivative(x, xi, sm, sp, ta) result(y)
611  ! -- return
612  real(dp) :: y
613  ! -- dummy variables
614  real(dp), intent(in) :: x
615  real(dp), intent(in) :: xi
616  real(dp), intent(in) :: sm
617  real(dp), intent(in) :: sp
618  real(dp), optional, intent(in) :: ta
619  ! -- local
620  real(dp) :: a
621  real(dp) :: b
622  real(dp) :: dx
623  real(dp) :: mu
624  real(dp) :: rho
625  !
626  ! -- set smoothing variable a
627  if (present(ta)) then
628  a = ta
629  else
630  a = dem8
631  end if
632  !
633  ! -- calculate b from smoothing variable a
634  b = a / (sqrt(dtwo) - done)
635  !
636  ! -- calculate contributions to derivative
637  dx = x - xi
638  mu = sqrt(dx**dtwo + b**dtwo - a**dtwo)
639  rho = dx / mu
640  !
641  ! -- calculate derivative from individual contributions
642  y = dhalf * (sm + sp) - dhalf * rho * (sm - sp)
643  end function sslopederivative
644 
645  !> @ brief sQuadratic0sp
646  !!
647  !! Nonlinear smoothing function returns a smoothed value of y that uses a
648  !! quadratic to smooth x over range of xi - epsilon to xi + epsilon.
649  !! Simplification of sQuadraticSlope with sm = 0, sp = 1, and yi = 0.
650  !! From Panday et al. (2013) - eq. 35 - https://dx.doi.org/10.5066/F7R20ZFJ
651  !<
652  function squadratic0sp(x, xi, tomega) result(y)
653  ! -- return
654  real(dp) :: y
655  ! -- dummy variables
656  real(dp), intent(in) :: x
657  real(dp), intent(in) :: xi
658  real(dp), optional, intent(in) :: tomega
659  ! -- local
660  real(dp) :: omega
661  real(dp) :: epsilon
662  real(dp) :: dx
663  !
664  ! -- set smoothing interval
665  if (present(tomega)) then
666  omega = tomega
667  else
668  omega = dem6
669  end if
670  !
671  ! -- set smoothing interval
672  epsilon = dhalf * omega
673  !
674  ! -- calculate distance from xi
675  dx = x - xi
676  !
677  ! -- evaluate smoothing function
678  if (dx < -epsilon) then
679  y = xi
680  else if (dx < epsilon) then
681  y = (dx**dtwo / (dfour * epsilon)) + dhalf * dx + (epsilon / dfour) + xi
682  else
683  y = x
684  end if
685  end function squadratic0sp
686 
687  !> @ brief sQuadratic0spDerivative
688  !!
689  !! Derivative of nonlinear smoothing function returns a smoothed value of y
690  !! that uses a quadratic to smooth x over range of xi - epsilon to xi + epsilon.
691  !! Simplification of sQuadraticSlope with sm = 0, sp = 1, and yi = 0.
692  !! From Panday et al. (2013) - eq. 35 - https://dx.doi.org/10.5066/F7R20ZFJ
693  !<
694  function squadratic0spderivative(x, xi, tomega) result(y)
695  ! -- return
696  real(dp) :: y
697  ! -- dummy variables
698  real(dp), intent(in) :: x
699  real(dp), intent(in) :: xi
700  real(dp), optional, intent(in) :: tomega
701  ! -- local
702  real(dp) :: omega
703  real(dp) :: epsilon
704  real(dp) :: dx
705  !
706  ! -- set smoothing interval
707  if (present(tomega)) then
708  omega = tomega
709  else
710  omega = dem6
711  end if
712  !
713  ! -- set smoothing interval
714  epsilon = dhalf * omega
715  !
716  ! -- calculate distance from xi
717  dx = x - xi
718  !
719  ! -- evaluate smoothing function
720  if (dx < -epsilon) then
721  y = 0
722  else if (dx < epsilon) then
723  y = (dx / omega) + dhalf
724  else
725  y = 1
726  end if
727  end function squadratic0spderivative
728 
729  !> @ brief sQuadraticSlope
730  !!
731  !! Quadratic smoothing function returns a smoothed value of y whose limbs are
732  !! the lines yi + (sm * dx) for x-values less than xi and yi + (sp * dx) for
733  !! x-values greater than xi, where dx = x - xi. The limbs are blended by a
734  !! quadratic over xi +/- epsilon, so the value equals yi at xi only in the
735  !! limit of zero smoothing; otherwise it differs from yi by a term
736  !! proportional to the smoothing interval.
737  !<
738  function squadraticslope(x, xi, yi, sm, sp, tomega) result(y)
739  ! -- return
740  real(dp) :: y
741  ! -- dummy variables
742  real(dp), intent(in) :: x
743  real(dp), intent(in) :: xi
744  real(dp), intent(in) :: yi
745  real(dp), intent(in) :: sm
746  real(dp), intent(in) :: sp
747  real(dp), optional, intent(in) :: tomega
748  ! -- local
749  real(dp) :: omega
750  real(dp) :: epsilon
751  real(dp) :: dx
752  real(dp) :: c
753  !
754  ! -- set smoothing interval
755  if (present(tomega)) then
756  omega = tomega
757  else
758  omega = dem6
759  end if
760  !
761  ! -- set smoothing interval
762  epsilon = dhalf * omega
763  !
764  ! -- calculate distance from xi
765  dx = x - xi
766  !
767  ! -- evaluate smoothing function
768  if (dx < -epsilon) then
769  y = sm * dx
770  else if (dx < epsilon) then
771  c = dx / epsilon
772  y = dhalf * epsilon * (dhalf * (sp - sm) * (done + c**dtwo) + (sm + sp) * c)
773  else
774  y = sp * dx
775  end if
776  !
777  ! -- add value at xi
778  y = y + yi
779  end function squadraticslope
780 
781  !> @ brief sQuadraticSlopeDerivative
782  !!
783  !! Derivative of sQuadraticSlope: smoothly transitions from the slope sm for
784  !! x-values less than xi to the slope sp for x-values greater than xi, blended
785  !! by a line over xi +/- epsilon, where dx = x - xi.
786  !<
787  function squadraticslopederivative(x, xi, sm, sp, tomega) result(y)
788  ! -- return
789  real(dp) :: y
790  ! -- dummy variables
791  real(dp), intent(in) :: x
792  real(dp), intent(in) :: xi
793  real(dp), intent(in) :: sm
794  real(dp), intent(in) :: sp
795  real(dp), optional, intent(in) :: tomega
796  ! -- local
797  real(dp) :: omega
798  real(dp) :: epsilon
799  real(dp) :: dx
800  real(dp) :: c
801  !
802  ! -- set smoothing interval
803  if (present(tomega)) then
804  omega = tomega
805  else
806  omega = dem6
807  end if
808  !
809  ! -- set smoothing interval
810  epsilon = dhalf * omega
811  !
812  ! -- calculate distance from xi
813  dx = x - xi
814  !
815  ! -- evaluate smoothing function
816  if (dx < -epsilon) then
817  y = sm
818  else if (dx < epsilon) then
819  c = dx / epsilon
820  y = dhalf * ((sp - sm) * c + (sm + sp))
821  else
822  y = sp
823  end if
824  end function squadraticslopederivative
825 
826 end module smoothingmodule
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dfour
real constant 4
Definition: Constants.f90:81
real(dp), parameter dem8
real constant 1e-8
Definition: Constants.f90:111
real(dp), parameter dem14
real constant 1e-14
Definition: Constants.f90:115
real(dp), parameter dhalf
real constant 1/2
Definition: Constants.f90:68
real(dp), parameter dem4
real constant 1e-4
Definition: Constants.f90:107
real(dp), parameter dem6
real constant 1e-6
Definition: Constants.f90:109
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
real(dp), parameter dem5
real constant 1e-5
Definition: Constants.f90:108
real(dp), parameter dprec
real constant machine precision
Definition: Constants.f90:120
real(dp), parameter dem2
real constant 1e-2
Definition: Constants.f90:105
real(dp), parameter dtwo
real constant 2
Definition: Constants.f90:79
real(dp), parameter dsix
real constant 6
Definition: Constants.f90:82
real(dp), parameter dthree
real constant 3
Definition: Constants.f90:80
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
This module defines variable data types.
Definition: kind.f90:8
real(dp) function svangenuchtensaturation(top, bot, x, alpha, beta, sr)
@ brief sQuadraticSaturation
subroutine slinear(x, range, dydx, y)
@ brief sLinear
real(dp) function squadraticsaturation(top, bot, x, eps)
@ brief sQuadraticSaturation
real(dp) function slinearsaturation(top, bot, x)
@ brief sLinearSaturation
real(dp) function scubicsaturation(top, bot, x, eps)
@ brief sCubicSaturation
real(dp) function squadraticslope(x, xi, yi, sm, sp, tomega)
@ brief sQuadraticSlope
real(dp) function sslope(x, xi, yi, sm, sp, ta)
@ brief sSlope
subroutine scubiclinear(x, range, dydx, y)
@ brief sCubicLinear
real(dp) function squadraticslopederivative(x, xi, sm, sp, tomega)
@ brief sQuadraticSlopeDerivative
subroutine sramp(x, range, dydx, y)
@ brief sRamp
real(dp) function squadraticsaturationderivative(top, bot, x, eps)
@ brief Derivative of the quadratic saturation function
subroutine squadratic(x, range, dydx, y)
@ brief sQuadratic
real(dp) function sslopederivative(x, xi, sm, sp, ta)
@ brief sSlopeDerivative
real(dp) function sqsaturationderivative(top, bot, x, c1, c2)
@ brief sQSaturationDerivative
subroutine schsmooth(d, smooth, dwdh)
@ brief sChSmooth
real(dp) function squadratic0spderivative(x, xi, tomega)
@ brief sQuadratic0spDerivative
subroutine sscurve(x, range, dydx, y)
@ brief SCurve
real(dp) function sqsaturation(top, bot, x, c1, c2)
@ brief sQSaturation
real(dp) function squadratic0sp(x, xi, tomega)
@ brief sQuadratic0sp
subroutine scubic(x, range, dydx, y)
@ brief sCubic