C $Header: /u/gcmpack/MITgcm/pkg/generic_advdiff/gad_ppm_fun.F,v 1.1 2016/03/13 01:44:03 jmc Exp $ C $Name: $ # include "GAD_OPTIONS.h" C-- File gad_ppm_fun.F: Routines to form PPM grid-cell polynomial. C-- Contents C-- o GAD_PPM_FUN_NULL C-- o GAD_PPM_FUN_MONO C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| SUBROUTINE GAD_PPM_FUN_NULL( I ff00, I fell,ferr, O fhat,mono) C |================================================================| C | PPM_FUN_NULL: form PPM grid-cell polynomial. | C | Piecewise Parabolic Method (PPM), unlimited variant. | C |================================================================| implicit none C ====================================================== arguments _RL ff00 _RL fell,ferr _RL fhat(+1:+3) integer mono mono = +0 C ============================================== unlimited profile fhat( 1 ) = & +(3. _d 0 / 2. _d 0) * ff00 & -(1. _d 0 / 4. _d 0) *(ferr+fell) fhat( 2 ) = & +(1. _d 0 / 2. _d 0) *(ferr-fell) fhat( 3 ) = & -(3. _d 0 / 2. _d 0) * ff00 & +(3. _d 0 / 4. _d 0) *(ferr+fell) return c end subroutine GAD_PPM_FUN_NULL end C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| SUBROUTINE GAD_PPM_FUN_MONO( I ff00, I ffll,ffrr, I fell,ferr, I dfds, O fhat,mono) C |================================================================| C | PPM_FUN_MONO: form PPM grid-cell polynomial. | C | Piecewise Parabolic Method (PPM) - monotonic variant. | C |================================================================| implicit none C ====================================================== arguments _RL ff00 _RL ffll,ffrr _RL fell,ferr _RL dfds(-1:+1) _RL fhat(+1:+3) integer mono C ====================================================== variables _RL turn mono = 0 C ============================================== "flatten" extrema if((ffrr-ff00) * & (ff00-ffll) .le. 0. _d 0) then mono = +1 fhat(1) = ff00 fhat(2) = 0. _d 0 fhat(3) = 0. _d 0 return end if C ============================================== limit edge values if((ffll-fell) * & (fell-ff00) .le. 0. _d 0) then mono = +1 fell = ff00 - dfds(0) end if if((ffrr-ferr) * & (ferr-ff00) .le. 0. _d 0) then mono = +1 ferr = ff00 + dfds(0) end if C ============================================== limit cell values fhat( 1 ) = & +(3. _d 0 / 2. _d 0) * ff00 & -(1. _d 0 / 4. _d 0) *(ferr+fell) fhat( 2 ) = & +(1. _d 0 / 2. _d 0) *(ferr-fell) fhat( 3 ) = & -(3. _d 0 / 2. _d 0) * ff00 & +(3. _d 0 / 4. _d 0) *(ferr+fell) if (abs(fhat(3)) .gt. & abs(fhat(2))*.5 _d 0) then turn = -0.5 _d 0 * fhat(2) & / fhat(3) if ((turn .ge. -1. _d 0) & .and.(turn .le. +0. _d 0)) then mono = +2 C ====================================== push TURN onto lower edge ferr = +3. _d 0 * ff00 & -2. _d 0 * fell end if if ((turn .gt. +0. _d 0) & .and.(turn .le. +1. _d 0)) then mono = +2 C ====================================== push TURN onto upper edge fell = +3. _d 0 * ff00 & -2. _d 0 * ferr end if end if if (mono .gt. +1) then C ====================================== re-calc. coeff. on demand fhat( 1 ) = & +(3. _d 0 / 2. _d 0) * ff00 & -(1. _d 0 / 4. _d 0) *(ferr+fell) fhat( 2 ) = & +(1. _d 0 / 2. _d 0) *(ferr-fell) fhat( 3 ) = & -(3. _d 0 / 2. _d 0) * ff00 & +(3. _d 0 / 4. _d 0) *(ferr+fell) end if return c end subroutine GAD_PPM_FUN_MONO end