25 #include "sll_assert.h"
26 #include "sll_memory.h"
27 #include "sll_working_precision.h"
41 sll_real64,
dimension(:),
pointer :: buf1d
42 sll_real64,
dimension(:),
pointer :: buf1d_out
43 sll_real64,
dimension(:),
pointer :: dtab
44 sll_real64,
dimension(:),
pointer :: ltab
45 sll_real64,
dimension(:),
pointer :: mtab
46 sll_real64,
dimension(:),
pointer :: alphax
47 sll_real64,
dimension(:),
pointer :: prim
48 sll_real64,
dimension(:),
pointer :: bufout0
49 sll_real64,
dimension(:),
pointer :: bufout
50 sll_real64,
dimension(:),
pointer :: p
56 procedure, pass(adv) :: initialize => &
58 procedure, pass(adv) :: advect_1d => &
60 procedure, pass(adv) :: advect_1d_constant => &
73 sll_int32,
intent(in) :: npts
74 sll_real64,
intent(in) :: eta_min
75 sll_real64,
intent(in) :: eta_max
76 sll_int32,
intent(in),
optional :: nbdr
79 sll_allocate(adv, ierr)
97 sll_int32,
intent(in) :: npts
98 sll_real64,
intent(in) :: eta_min
99 sll_real64,
intent(in) :: eta_max
100 sll_int32,
intent(in),
optional :: nbdr
106 adv%eta_min = eta_min
107 adv%eta_max = eta_max
109 sll_allocate(adv%buf1d(npts), ierr)
110 sll_allocate(adv%buf1d_out(npts), ierr)
113 if (
present(nbdr))
then
121 sll_allocate(adv%dtab(0:nx - 1), ierr)
122 sll_allocate(adv%ltab(0:nx - 2), ierr)
123 sll_allocate(adv%mtab(0:nx - 1), ierr)
124 sll_allocate(adv%alphax(0:nx - 1), ierr)
125 sll_allocate(adv%prim(-adv%Nbdr:nx - 1 + adv%Nbdr), ierr)
126 sll_allocate(adv%bufout0(0:nx - 1 + 2*adv%Nbdr), ierr)
127 sll_allocate(adv%bufout(0:nx), ierr)
128 sll_allocate(adv%p(0:nx - 1), ierr)
133 adv%ltab(i) = 1._f64/adv%dtab(i)
134 adv%dtab(i + 1) = 4._f64 - adv%ltab(i)
135 adv%mtab(i + 1) = -adv%mtab(i)/adv%dtab(i)
137 adv%ltab(nx - 2) = (1._f64 + adv%mtab(nx - 2))/adv%dtab(nx - 2)
138 adv%dtab(nx - 1) = 4._f64 - adv%ltab(nx - 2)*(adv%mtab(nx - 2) + 1._f64)
140 adv%dtab(nx - 1) = adv%dtab(nx - 1) + adv%mtab(i)*adv%mtab(i + 1)
143 adv%dtab(i) = 1._f64/adv%dtab(i)
161 sll_real64,
dimension(:),
intent(in) :: a
162 sll_real64,
intent(in) :: dt
163 sll_real64,
dimension(:),
intent(in) :: input
164 sll_real64,
dimension(:),
intent(out) :: output
191 dtmp2 = 1._f64/(adv%eta_max - adv%eta_min)
193 dx = 1._f64/real(nx, f64)
195 adv%alphax(0:nx - 1) = 0._f64
201 x = real(i, f64)*dx - adv%alphax(i)
202 if (x >= 1._f64)
then
211 ix = floor(x*real(nx, f64))
212 if ((x >= 1._f64) .or. (x < 0._f64))
then
213 print *,
'#x too big or too small'
214 print *,
'#in PSM_advect_1d'
215 print *, x, nx, ix, i, s, adv%alphax(i)
225 result = (1._f64 - x)*a(ix + 1) + x*a(ix1 + 1)
226 adv%alphax(i) = result*dtmp2*dt_loc
230 dtmp2 = adv%alphax(nx - 1)
232 adv%alphax(i) = adv%alphax(i) + adv%alphax(i - 1)
234 adv%alphax(0) = adv%alphax(0) + dtmp2
254 adv%p(0:nx - 1) = input(1:nx)
255 m = sum(adv%p(0:nx - 1))
256 adv%prim(0) = adv%p(0)
258 adv%prim(i) = adv%prim(i - 1) + adv%p(i)
262 adv%prim(i) = adv%prim(i + nx) - m
264 do i = nx, nx + nbdr - 1
265 adv%prim(i) = adv%prim(i - nx) + m
269 adv%bufout0(i + nbdr) = 3._f64*(adv%p(i) + adv%p(mod(i + nx - 1, nx)))
272 adv%bufout0(i + nbdr) = adv%bufout0(i + nbdr) - adv%bufout0(i - 1 + nbdr)*adv%ltab(i - 1)
275 adv%bufout0(nx - 1 + nbdr) = adv%bufout0(nx - 1 + nbdr) + adv%mtab(i + 1)*adv%bufout0(i + nbdr)
277 adv%bufout0(nx - 1 + nbdr) = adv%bufout0(nx - 1 + nbdr)*adv%dtab(nx - 1)
278 adv%bufout0(nx - 2 + nbdr) = adv%dtab(nx - 2)*(adv%bufout0(nx - 2 + nbdr) &
279 - (1._f64 + adv%mtab(nx - 2))*adv%bufout0(nx - 1 + nbdr))
281 adv%bufout0(i + nbdr) = adv%dtab(i) &
282 *(adv%bufout0(i + nbdr) - adv%bufout0(i + 1 + nbdr) - adv%mtab(i)*adv%bufout0(nx - 1 + nbdr))
285 adv%bufout0(i) = adv%bufout0(nx + i)
288 adv%bufout0(nx + nbdr + i) = adv%bufout0(nbdr + i)
306 x = real(i, f64)*dx - adv%alphax(mod(i, nx))
307 ix = floor(x*real(nx, f64))
308 x = x*real(nx, f64) - real(ix, f64)
313 if ((x < 0._f64) .or. (x >= 1._f64))
then
314 print *,
'#Localization problem in PSM_advect_1d'
315 print *, x, ix, nx, adv%alphax(mod(i, nx))
318 df0 = adv%bufout0(ix + nbdr)
319 df1 = adv%bufout0(ix + 1 + nbdr)
320 tmp = adv%p(mod(ix + nx, nx))
321 w(0) = x*(x - 1._f64)*(x - 1._f64)
322 w(1) = x*x*(x - 1._f64)
323 w(2) = x*x*(3._f64 - 2._f64*x)
324 result = w(0)*df0 + w(1)*df1 + w(2)*tmp
325 adv%bufout(i) = result + adv%prim(ix - 1)
329 output(i + 1) = adv%bufout(i + 1) - adv%bufout(i)
332 output(nx + 1) = output(1)
359 sll_real64,
intent(in) :: a
360 sll_real64,
intent(in) :: dt
361 sll_real64,
dimension(:),
intent(in) :: input
362 sll_real64,
dimension(:),
intent(out) :: output
367 sll_assert(storage_size(adv) > 0)
368 output = input + a*dt
375 sll_deallocate(adv%buf1d, ierr)
376 sll_deallocate(adv%buf1d_out, ierr)
377 sll_deallocate(adv%dtab, ierr)
378 sll_deallocate(adv%ltab, ierr)
379 sll_deallocate(adv%mtab, ierr)
380 sll_deallocate(adv%alphax, ierr)
381 sll_deallocate(adv%prim, ierr)
382 sll_deallocate(adv%bufout0, ierr)
383 sll_deallocate(adv%bufout, ierr)
384 sll_deallocate(adv%p, ierr)
Abstract class for advection.
subroutine delete_psm_1d_advector(adv)
subroutine initialize_psm_1d_advector(adv, Npts, eta_min, eta_max, Nbdr)
subroutine psm_advect_1d(adv, A, dt, input, output)
type(psm_1d_advector) function, pointer, public sll_f_new_psm_1d_advector(Npts, eta_min, eta_max, Nbdr)
subroutine psm_advect_1d_constant(adv, A, dt, input, output)