Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_advection_1d_PSM.F90
Go to the documentation of this file.
1 !**************************************************************
2 ! Copyright INRIA
3 ! Authors :
4 ! CALVI project team
5 !
6 ! This code SeLaLib (for Semi-Lagrangian-Library)
7 ! is a parallel library for simulating the plasma turbulence
8 ! in a tokamak.
9 !
10 ! This software is governed by the CeCILL-B license
11 ! under French law and abiding by the rules of distribution
12 ! of free software. You can use, modify and redistribute
13 ! the software under the terms of the CeCILL-B license as
14 ! circulated by CEA, CNRS and INRIA at the following URL
15 ! "http://www.cecill.info".
16 !**************************************************************
17 
18 ! in development; should be at least cubic splines
19 ! attached with computation of characteristics
20 
24 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
25 #include "sll_assert.h"
26 #include "sll_memory.h"
27 #include "sll_working_precision.h"
28 
29  use sll_m_advection_1d_base, only: &
31 
32  implicit none
33 
34  public :: &
36 
37  private
38 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
39 
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
51  sll_real64 :: eta_min
52  sll_real64 :: eta_max
53  sll_int32 :: npts
54  sll_int32 :: nbdr
55  contains
56  procedure, pass(adv) :: initialize => &
58  procedure, pass(adv) :: advect_1d => &
60  procedure, pass(adv) :: advect_1d_constant => &
62  procedure, pass(adv) :: delete => delete_psm_1d_advector
63  end type psm_1d_advector
64 
65 contains
67  Npts, &
68  eta_min, &
69  eta_max, &
70  Nbdr) &
71  result(adv)
72  type(psm_1d_advector), pointer :: adv
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
77  sll_int32 :: ierr
78 
79  sll_allocate(adv, ierr)
80 
82  adv, &
83  npts, &
84  eta_min, &
85  eta_max, &
86  nbdr)
87 
88  end function sll_f_new_psm_1d_advector
89 
91  adv, &
92  Npts, &
93  eta_min, &
94  eta_max, &
95  Nbdr)
96  class(psm_1d_advector), intent(inout) :: adv
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
101  sll_int32 :: ierr
102  sll_int32 :: i
103  sll_int32 :: nx
104 
105  adv%Npts = npts
106  adv%eta_min = eta_min
107  adv%eta_max = eta_max
108 
109  sll_allocate(adv%buf1d(npts), ierr)
110  sll_allocate(adv%buf1d_out(npts), ierr)
111  nx = npts - 1
112 
113  if (present(nbdr)) then
114  adv%Nbdr = nbdr
115  else
116  adv%Nbdr = 100
117  end if
118 
119  !print *,Nx,adv%Nbdr
120 
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)
129 
130  adv%dtab(0) = 4._f64
131  adv%mtab(0) = 1._f64
132  do i = 0, nx - 3
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)
136  end do
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)
139  do i = 0, nx - 3
140  adv%dtab(nx - 1) = adv%dtab(nx - 1) + adv%mtab(i)*adv%mtab(i + 1)
141  end do
142  do i = 0, nx - 1
143  adv%dtab(i) = 1._f64/adv%dtab(i)
144  end do
145 
146 ! dtab= (double*) malloc(sizeof(double)*(Nx));ltab= (double*) malloc(sizeof(double)*(Nx-1));
147 !mtab= (double*) malloc(sizeof(double)*(Nx));
148 ! dtab[0]=4.;mtab[0]=1.;for(i=0;i<Nx-2 ;i++){ltab[i]=1./dtab[i];dtab[i+1]=4.-ltab[i];mtab[i+1]=-mtab[i]/dtab[i];}
149 ! ltab[Nx-2]=(1.+mtab[Nx-2])/dtab[Nx-2];dtab[Nx-1]=4-ltab[Nx-2]*(mtab[Nx-2]+1);
150 ! for(i=0;i<Nx-2;i++)dtab[Nx-1]=dtab[Nx-1]+mtab[i]*mtab[i+1];for(i=0;i<Nx;i++)dtab[i]=1./dtab[i];
151 
152  end subroutine initialize_psm_1d_advector
153 
154  subroutine psm_advect_1d( &
155  adv, &
156  A, &
157  dt, &
158  input, &
159  output)
160  class(psm_1d_advector) :: adv
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
165  sll_int32 :: npts
166  sll_int32 :: nbdr
167  sll_int32 :: i
168  sll_int32 :: nx
169  sll_int32 :: s
170  sll_real64 :: dtmp2
171  sll_real64 :: x
172  sll_real64 :: dx
173  sll_int32 :: ix
174  sll_int32 :: ix1
175  sll_real64 :: result
176  sll_real64 :: m
177  sll_real64 :: w(0:2)
178  sll_real64 :: tmp
179  sll_real64 :: df0
180  sll_real64 :: df1
181  sll_real64 :: dt_loc
182 
183  dt_loc = 0.5_f64*dt
184 
185  npts = adv%Npts
186 
187  nbdr = adv%Nbdr
188 
189  nx = npts - 1
190 
191  dtmp2 = 1._f64/(adv%eta_max - adv%eta_min)
192 
193  dx = 1._f64/real(nx, f64)
194 
195  adv%alphax(0:nx - 1) = 0._f64
196 
197  !print *,size(A),Nx,Npts,size(adv%alphax)
198 
199  do i = 0, nx - 1
200  do s = 0, 9
201  x = real(i, f64)*dx - adv%alphax(i)
202  if (x >= 1._f64) then
203  x = x - 1._f64
204  end if
205  if (x < 0._f64) then
206  x = x + 1._f64
207  end if
208  if (x == 1) then
209  x = 0._f64
210  end if
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)
216  stop
217  end if
218  ix1 = ix + 1
219  if (ix1 == nx) then
220  ix1 = 0
221  end if
222 
223  !print *,'ix=',i,s,ix,ix1,x,dtmp2,adv%alphax(i),dt
224 
225  result = (1._f64 - x)*a(ix + 1) + x*a(ix1 + 1)
226  adv%alphax(i) = result*dtmp2*dt_loc
227  end do
228  end do
229 
230  dtmp2 = adv%alphax(nx - 1)
231  do i = nx - 1, 1, -1
232  adv%alphax(i) = adv%alphax(i) + adv%alphax(i - 1)
233  end do
234  adv%alphax(0) = adv%alphax(0) + dtmp2
235 
236 ! dtmp2=1./(xmax-xmin);dtmp3=1./(ymax-ymin);
237 ! #ifdef PTFX1D
238 ! for(i=0;i<Nx*Ny;i++)alphax[i]=0.;
239 ! //for(s=0;s<10;s++)for(i=0;i<Nx;i++)for(j=1;j<Ny;j++){
240 ! for(j=0;j<Ny;j++){p=&alphax[Nx*j];for(i=0;i<Nx;i++)for(s=0;s<10;s++){
241 ! //localization of x,y ix and iy
242 ! x=i*dx-p[i];if(x>=1.)x-=1.;if(x<0.)x+=1.;if(x>=1.)x-=1.;ix=(int)(x*Nx);
243 ! if(x>=1. || x<0.){fprintf(stderr,"x too big/small %1.1000lg i=%d j=%d\n",x,i,j);exit(1);}
244 ! assert(x>=0.&&x<1.);assert(ix>=0 &&ix<Nx);x=x*Nx-ix;assert(x>=0 &&x<1.);
245 ! ix1=ix+1;if(ix1==Nx)ix1=0;
246 ! //result=(1.-x)*Ey[j+(Ny+1)*ix]+x*Ey[j+(Ny+1)*ix1];alphax[(i+Nx*j)]=result*dtmp2*dt;
247 ! result=(1.-x)*Ey[ix+Nx*j]+x*Ey[ix1+Nx*j];p[i]=result*dtmp2*dt;
248 ! }}
249 
250 ! if(interp==5 || interp==11 || interp==6 || interp<0){
251 ! for(j=0;j<Ny;j++){p=&alphax[Nx*j];dtmp2=p[Nx-1];for(i=Nx-1;i>0;i--)p[i]=(p[i]+p[i-1]);p[0]=(p[0]+dtmp2);
252 ! }
253 
254  adv%p(0:nx - 1) = input(1:nx)
255  m = sum(adv%p(0:nx - 1))
256  adv%prim(0) = adv%p(0)
257  do i = 1, nx - 1
258  adv%prim(i) = adv%prim(i - 1) + adv%p(i)
259  end do
260 
261  do i = -nbdr, -1
262  adv%prim(i) = adv%prim(i + nx) - m
263  end do
264  do i = nx, nx + nbdr - 1
265  adv%prim(i) = adv%prim(i - nx) + m
266  end do
267 
268  do i = 0, nx - 1
269  adv%bufout0(i + nbdr) = 3._f64*(adv%p(i) + adv%p(mod(i + nx - 1, nx)))
270  end do
271  do i = 1, nx - 1
272  adv%bufout0(i + nbdr) = adv%bufout0(i + nbdr) - adv%bufout0(i - 1 + nbdr)*adv%ltab(i - 1)
273  end do
274  do i = 0, nx - 3
275  adv%bufout0(nx - 1 + nbdr) = adv%bufout0(nx - 1 + nbdr) + adv%mtab(i + 1)*adv%bufout0(i + nbdr)
276  end do
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))
280  do i = nx - 3, 0, -1
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))
283  end do
284  do i = 0, nbdr - 1
285  adv%bufout0(i) = adv%bufout0(nx + i)
286  end do
287  do i = 0, nbdr - 1
288  adv%bufout0(nx + nbdr + i) = adv%bufout0(nbdr + i)
289  end do
290 
291 ! M=0.;for(i=0;i<Nx;i++)M+=p[i];prim[0]=p[0];
292 ! for(i=1;i<Nx;i++)prim[i]=prim[i-1]+p[i];
293 ! for(i=-Nbdr;i<0;i++)prim[i]=prim[i+Nx]-M;for(i=Nx;i<Nx+Nbdr;i++)prim[i]=prim[i-Nx]+M;
294 ! for(i=0;i<Nx;i++)bufout0[i+Nbdr]=3*(p[i]+p[(i+Nx-1)%Nx]);
295 ! /*resolution of L phi = ftab*/
296 ! for(i=1;i<Nx;i++) bufout0[i+Nbdr]-=bufout0[i-1+Nbdr]*ltab[i-1];
297 ! for(i=0;i<Nx-2;i++)bufout0[Nx-1+Nbdr]+=mtab[i+1]*bufout0[i+Nbdr];
298 ! /*resolution of U eta =phi*/
299 ! bufout0[Nx-1+Nbdr]*=dtab[Nx-1];
300 ! bufout0[Nx-2+Nbdr]=dtab[Nx-2]*(bufout0[Nx-2+Nbdr]-(1.+mtab[Nx-2])*bufout0[Nx-1+Nbdr]);
301 ! for(i=Nx-3;i>=0;i--) bufout0[i+Nbdr]=dtab[i]*(bufout0[i+Nbdr]-bufout0[i+1+Nbdr]-mtab[i]*bufout0[Nx-1+Nbdr]);
302 ! for(i=0;i<Nbdr;i++)bufout0[i]=bufout0[Nx+i];
303 ! for(i=0;i<Nbdr;i++)bufout0[Nx+Nbdr+i]=bufout0[Nbdr+i];
304 
305  do i = 0, nx
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)
309  if (x == 1) then
310  x = 0._f64
311  ix = ix - 1
312  end if
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))
316  stop
317  end if
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)
326  end do
327 
328  do i = 0, nx - 1
329  output(i + 1) = adv%bufout(i + 1) - adv%bufout(i)
330  end do
331 
332  output(nx + 1) = output(1)
333 
334 ! for(i=0;i<Nx+1;i++){
335 ! //i1=(i-1+Nx)%Nx;
336 ! x=(i)*dx-alphax[i%Nx];
337 ! ix=floor(x*Nx);
338 ! assert(x>-1.&&x<2.);assert(ix-1>=-Nbdr &&ix+1<Nx+Nbdr);x=x*Nx-ix;assert(x>=0 &&x<1.);
339 ! if(x>=2. || x<=-1.){fprintf(stderr,"x too big/small %1.1000lg i=%d j=%d\n",x,i,j);exit(1);}
340 ! df0=bufout0[ix+Nbdr];df1=bufout0[ix+1+Nbdr];tmp=p[(ix+Nx)%Nx];
341 ! lim(tmp,df0,df1);
342 ! w[0]=x*(x-1)*(x-1);
343 ! w[1]=x*x*(x-1);
344 ! w[2]=x*x*(3-2*x);
345 ! result=w[0]*df0+w[1]*df1+w[2]*tmp;
346 ! bufout[i]=result+prim[ix-1];
347 ! }
348 !for(i=0;i<Nx;i++)p[i]=bufout[i+1]-bufout[i];
349 
350  end subroutine psm_advect_1d
351 
353  adv, &
354  A, &
355  dt, &
356  input, &
357  output)
358  class(psm_1d_advector) :: adv
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
363 
364  !this version is not optimized
365 
366  return
367  sll_assert(storage_size(adv) > 0)
368  output = input + a*dt
369 
370  end subroutine psm_advect_1d_constant
371 
372  subroutine delete_psm_1d_advector(adv)
373  class(psm_1d_advector), intent(inout) :: adv
374  sll_int32 :: ierr
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)
385  end subroutine delete_psm_1d_advector
386 
387 end module sll_m_advection_1d_psm
Abstract class for advection.
Parabolic Spline Method.
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)
    Report Typos and Errors