New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
p3e.h90 in vendors/PPR/src – NEMO

source: vendors/PPR/src/p3e.h90 @ 14212

Last change on this file since 14212 was 14212, checked in by jchanut, 4 years ago

#2222, update PPR library to circumvent issues found with cpp directives: remove timing instructions. Changed main module extension in .F90 to comply with FCM rules (no effect).

File size: 8.1 KB
Line 
1
2    !
3    ! This program may be freely redistributed under the
4    ! condition that the copyright notices (including this
5    ! entire header) are not removed, and no compensation
6    ! is received through use of the software.  Private,
7    ! research, and institutional use is free.  You may
8    ! distribute modified versions of this code UNDER THE
9    ! CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE
10    ! TO IT IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE
11    ! ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE
12    ! MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR
13    ! NOTICE IS GIVEN OF THE MODIFICATIONS.  Distribution
14    ! of this code as part of a commercial system is
15    ! permissible ONLY BY DIRECT ARRANGEMENT WITH THE
16    ! AUTHOR.  (If you are not directly supplying this
17    ! code to a customer, and you are instead telling them
18    ! how they can obtain it for free, then you are not
19    ! required to make any arrangement with me.)
20    !
21    ! Disclaimer:  Neither I nor: Columbia University, the
22    ! National Aeronautics and Space Administration, nor
23    ! the Massachusetts Institute of Technology warrant
24    ! or certify this code in any way whatsoever.  This
25    ! code is provided "as-is" to be used at your own risk.
26    !
27    !
28
29    !   
30    ! P3E.h90: set edge estimates via degree-3 polynomials.
31    !
32    ! Darren Engwirda
33    ! 09-Sep-2016
34    ! de2363 [at] columbia [dot] edu
35    !
36    !
37   
38    subroutine p3e(npos,nvar,ndof,delx, &
39        &          fdat,bclo,bchi,edge, &
40        &          dfdx,opts,dmin)
41
42    !
43    ! NPOS  no. edges over grid.
44    ! NVAR  no. state variables.
45    ! NDOF  no. degrees-of-freedom per grid-cell.
46    ! DELX  grid-cell spacing array. LENGTH(DELX) == +1 if
47    !       spacing is uniform .
48    ! FDAT  grid-cell moments array. FDAT is an array with
49    !       SIZE = NDOF-by-NVAR-by-NPOS-1 .
50    ! BCLO  boundary condition at lower endpoint.
51    ! BCHI  boundary condition at upper endpoint.
52    ! EDGE  edge-centred interp. for function-value. EDGE
53    !       is an array with SIZE = NVAR-by-NPOS .
54    ! DFDX  edge-centred interp. for 1st-derivative. DFDX
55    !       is an array with SIZE = NVAR-by-NPOS .
56    ! OPTS  method parameters. See RCON-OPTS for details .
57    ! DMIN  min. grid-cell spacing thresh .
58    !
59
60        implicit none
61
62    !------------------------------------------- arguments !
63        integer, intent( in) :: npos,nvar,ndof
64        real*8 , intent( in) :: delx(:)
65        real*8 , intent( in) :: fdat(:,:,:)
66        type (rcon_ends), intent(in) :: bclo(:)
67        type (rcon_ends), intent(in) :: bchi(:)
68        real*8 , intent(out) :: edge(:,:)
69        real*8 , intent(out) :: dfdx(:,:)
70        real*8 , intent( in) :: dmin
71        class(rcon_opts), intent(in) :: opts
72
73    !------------------------------------------- variables !
74        integer :: ipos,ivar,idof,head,tail
75        logical :: okay
76        real*8  :: xhat,fEPS
77        real*8  :: delh(-2:+1)
78        real*8  :: xmap(-2:+2)
79        real*8  :: fhat(+4, nvar)
80        real*8  :: ivec(+4,-2:+2)
81        real*8  :: cmat(+4,+4)
82       
83        integer, parameter :: NSIZ = +4
84        real*8 , parameter :: ZERO = 1.d-14 
85   
86        head = +3 ; tail = npos - 2
87
88        if (npos.le.4) then
89    !----- default to reduced order if insufficient points !
90            call p1e (npos,nvar,ndof, &
91        &             delx,fdat,bclo, &
92        &             bchi,edge,dfdx, &
93        &             opts,dmin)
94        end if
95
96        if (npos.le.4) return
97
98    !------ impose value/slope B.C.'s about lower endpoint !
99
100        call pbc(npos,nvar,ndof,delx, &
101        &        fdat,bclo,edge,dfdx, &
102        &        -1  ,dmin)
103
104    !------ impose value/slope B.C.'s about upper endpoint !
105
106        call pbc(npos,nvar,ndof,delx, &
107        &        fdat,bchi,edge,dfdx, &
108        &        +1  ,dmin)
109
110    ! Reconstruct edge-centred 4th-order polynomials. Com- !
111    ! pute values/slopes at edges directly. Mid.-order ex- !
112    ! trapolation at endpoints.                            !
113   
114        if (size(delx).eq.+1) then
115       
116            do  ipos = head , tail
117   
118    !--------------- reconstruction: constant grid-spacing !
119           
120            do  ivar = 1, nvar
121
122                edge(ivar,ipos) = ( &
123        &     -      1.d0 * &
124        &       fdat(1,ivar,ipos-2) &
125        &     +      7.d0 * &
126        &       fdat(1,ivar,ipos-1) &
127        &     +      7.d0 * &
128        &       fdat(1,ivar,ipos+0) &
129        &     -      1.d0 * &
130        &       fdat(1,ivar,ipos+1) ) / 12.d0
131           
132                dfdx(ivar,ipos) = ( &
133        &     +      1.d0 * &
134        &       fdat(1,ivar,ipos-2) &
135        &     -     15.d0 * &
136        &       fdat(1,ivar,ipos-1) &
137        &     +     15.d0 * &
138        &       fdat(1,ivar,ipos+0) &
139        &     -      1.d0 * &
140        &       fdat(1,ivar,ipos+1) ) / 12.d0
141
142                dfdx(ivar,ipos) = &
143        &       dfdx(ivar,ipos) / delx(+1)
144
145            end do
146                     
147            end do
148       
149        else
150       
151            fEPS     = ZERO * dmin
152
153            do  ipos = head , tail
154   
155    !--------------- reconstruction: variable grid-spacing !
156           
157            delh(-2) = delx(ipos-2)
158            delh(-1) = delx(ipos-1)
159            delh(+0) = delx(ipos+0)
160            delh(+1) = delx(ipos+1)
161
162            xhat = .5d0 * max(delh(-1),dmin) + &
163        &          .5d0 * max(delh(+0),dmin)
164
165            xmap(-2) = -( delh(-2) &
166        &              +  delh(-1) ) / xhat
167            xmap(-1) = -  delh(-1)   / xhat
168            xmap(+0) = +  0.d0
169            xmap(+1) = +  delh(+0)   / xhat
170            xmap(+2) = +( delh(+0) &
171        &              +  delh(+1) ) / xhat
172           
173    !--------------------------- calc. integral basis vec. !
174
175            do  idof = -2, +2
176
177            ivec(1,idof) = &
178        &       xmap(idof) ** 1 / 1.0d+0
179            ivec(2,idof) = &
180        &       xmap(idof) ** 2 / 2.0d+0
181            ivec(3,idof) = &
182        &       xmap(idof) ** 3 / 3.0d+0
183            ivec(4,idof) = &
184        &       xmap(idof) ** 4 / 4.0d+0
185       
186            end do
187
188    !--------------------------- linear system: lhs matrix !
189
190            do  idof = +1, +4
191
192            cmat(1,idof) = ivec(idof,-1) &
193        &                - ivec(idof,-2)
194            cmat(2,idof) = ivec(idof,+0) &
195        &                - ivec(idof,-1)
196            cmat(3,idof) = ivec(idof,+1) &
197        &                - ivec(idof,+0)
198            cmat(4,idof) = ivec(idof,+2) &
199        &                - ivec(idof,+1)
200
201            end do
202
203    !--------------------------- linear system: rhs vector !
204
205            do  ivar = +1, nvar
206
207            fhat(+1,ivar) = &
208        &       delx(ipos-2) * &
209        &   fdat(+1,ivar,ipos-2) / xhat
210            fhat(+2,ivar) = &
211        &       delx(ipos-1) * &
212        &   fdat(+1,ivar,ipos-1) / xhat
213            fhat(+3,ivar) = &
214        &       delx(ipos+0) * &
215        &   fdat(+1,ivar,ipos+0) / xhat
216            fhat(+4,ivar) = &
217        &       delx(ipos+1) * &
218        &   fdat(+1,ivar,ipos+1) / xhat
219       
220            end do
221           
222    !------------------------- factor/solve linear systems !
223
224            call slv_4x4(cmat,NSIZ,fhat, &
225       &                 NSIZ,nvar,fEPS, &
226       &                 okay)
227
228            if (okay .eqv. .true.) then
229
230            do  ivar =  +1, nvar
231
232            edge(ivar,ipos) = fhat(1,ivar)
233                 
234            dfdx(ivar,ipos) = fhat(2,ivar) &
235        &                   / xhat
236       
237            end do
238
239            else
240
241    !------------------------- fallback if system singular !
242
243#           ifdef __PPR_WARNMAT__
244           
245            write(*,*) &
246    &   "WARNING::P3E - matrix-is-singular!"
247
248#           endif
249
250            do  ivar =  +1, nvar
251
252            edge(ivar,ipos) =   &
253        &   fdat(1,ivar,ipos-1) * 0.5d+0 + &
254        &   fdat(1,ivar,ipos-0) * 0.5d+0
255       
256            dfdx(ivar,ipos) =   &
257        &   fdat(1,ivar,ipos-0) * 1.0d+0 - &
258        &   fdat(1,ivar,ipos-1) * 1.0d+0
259                 
260            dfdx(ivar,ipos) =   &
261        &       dfdx(ivar,ipos) / xhat
262       
263            end do
264
265            end if
266       
267            end do
268       
269        end if
270
271        return
272       
273    end subroutine
274
275
276
Note: See TracBrowser for help on using the repository browser.