Modified implementation of Koren limiter, to avoid division and the min/max functions, which can be problematic / expensive. In most literature, you have r = a / b (ratio of gradients). Then the limiter phi(r) is multiplied with b. With this implementation, you get phi(r) * b
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(in) | :: | a |
Density gradient (numerator) |
||
| real(kind=dp), | intent(in) | :: | b |
Density gradient (denominator) |
pure real(dp) function koren(a, b) real(dp), intent(in) :: a !< Density gradient (numerator) real(dp), intent(in) :: b !< Density gradient (denominator) real(dp), parameter :: third = 1/3.0_dp real(dp) :: aa, ab aa = a * a ab = a * b if (ab <= 0) then ! a and b have different sign or one of them is zero, so r is either 0, ! inf or negative (special case a == b == 0 is ignored) koren = 0 else if (aa <= 0.25_dp * ab) then ! 0 < a/b <= 1/4, limiter has value 2*a/b koren = 2*a else if (aa <= 2.5_dp * ab) then ! 1/4 < a/b <= 2.5, limiter has value (1+2*a/b)/3 koren = third * (b + 2*a) else ! (1+2*a/b)/6 >= 1, limiter has value 2 koren = 2*b end if end function koren