MPI-AMRVAC  3.0
The MPI - Adaptive Mesh Refinement - Versatile Advection Code
mod_pfss.t
Go to the documentation of this file.
1 !> module mod_pfss.t -- potential field source surface model
2 !> PURPOSE : to extrapolate global potential magnetic field of the sun from
3 !> synoptic magnetograms
4 !> 2013.11.04 Developed by S. Moschou and C. Xia
5 !> 2014.04.01 Allow to change source surface (C. Xia)
6 !> PRECONDITIONS:
7 !> 1. 3D spherical coordinates
8 !> 2. A synoptic magnetogram in a binary file contains nphi, ntheta,
9 !> theta(ntheta), phi(nphi), B_r(nphi,ntheta) succesively.
10 !> 3. nphi, ntheta are long integers and other arrays are double precision.
11 !> theta contains decreasing radians with increasing indice (Pi to 0)
12 !> phi contains increasing radians with increasing indice (0 to 2*Pi)
13 !> USAGE:
14 !> example for a magnetogram with name 'mdicr2020.dat':
15 !>
16 !> subroutine initglobaldata_usr
17 !> ...
18 !> R_0=1.d0 ! dimensionless Solar radius (default 1.0)
19 !> R_s=2.5d0 ! dimensionless radius of source surface (default 2.5)
20 !> lmax=120 ! use a fixed value instead of the value determined by the
21 !> resolution of input magnetogram
22 !> trunc=.true. ! use less spherical harmonics at larger distances
23 !> call harm_coef('mdicr2020.dat')
24 !> end subroutine initglobaldata_usr
25 !>
26 !> subroutine initonegrid_usr(ixI^L,ixO^L,w,x)
27 !> ...
28 !> double precision :: bpf(ixI^S,1:ndir)
29 !> ...
30 !> call pfss(ixI^L,ixO^L,bpf,x)
31 !> w(ix^S,mag(:))=bpf(ix^S,:)
32 !>
33 !> end subroutine initonegrid_usr
34 module mod_pfss
35  implicit none
36  private
37 
38  double complex, allocatable :: flm(:,:),Alm(:,:),Blm(:,:)
39  double precision, allocatable :: Rlm(:,:), xrg(:)
40  double precision, public :: r_s=2.5d0, r_0=1.d0
41  integer, allocatable :: lmaxarray(:)
42  integer, public :: lmax=0
43  logical, public :: trunc=.false.
44 
45  public :: harm_coef
46 {^ifthreed
47  public :: pfss
48 }
49 
50 contains
51 
52  subroutine harm_coef(mapname)
54 
55  double precision, allocatable :: b_r0(:,:)
56  double precision, allocatable :: theta(:),phi(:),cfwm(:)
57  double precision :: rsl,xrl,dxr
58  integer :: xm,ym,l,m,amode,file_handle,il,ir,nlarr,nsh
59  integer, dimension(MPI_STATUS_SIZE) :: statuss
60  character(len=*) :: mapname
61  character(len=80) :: fharmcoef
62  logical :: aexist
63 
64  fharmcoef=mapname//'.coef'
65  inquire(file=fharmcoef, exist=aexist)
66  if(aexist) then
67  if(mype==0) then
68  call mpi_file_open(mpi_comm_self,fharmcoef,mpi_mode_rdonly, &
69  mpi_info_null,file_handle,ierrmpi)
70  call mpi_file_read(file_handle,lmax,1,mpi_integer,statuss,ierrmpi)
71  allocate(flm(0:lmax,0:lmax))
72  call mpi_file_read(file_handle,flm,(lmax+1)*(lmax+1),&
73  mpi_double_complex,statuss,ierrmpi)
74  call mpi_file_close(file_handle,ierrmpi)
75  end if
76  call mpi_barrier(icomm,ierrmpi)
77  if(npe>0) call mpi_bcast(lmax,1,mpi_integer,0,icomm,ierrmpi)
78  if(mype/=0) allocate(flm(0:lmax,0:lmax))
79  call mpi_barrier(icomm,ierrmpi)
80  if(npe>0) call mpi_bcast(flm,(lmax+1)*(lmax+1),mpi_double_complex,0,icomm,&
81  ierrmpi)
82  else
83  if(mype==0) then
84  inquire(file=mapname,exist=aexist)
85  if(.not. aexist) then
86  if(mype==0) write(*,'(2a)') "can not find file:",mapname
87  call mpistop("no input magnetogram found")
88  end if
89  call mpi_file_open(mpi_comm_self,mapname,mpi_mode_rdonly,mpi_info_null,&
90  file_handle,ierrmpi)
91  call mpi_file_read(file_handle,xm,1,mpi_integer,statuss,ierrmpi)
92  call mpi_file_read(file_handle,ym,1,mpi_integer,statuss,ierrmpi)
93  if(lmax==0) lmax=min(2*ym/3,xm/3)
94 
95  allocate(b_r0(xm,ym))
96  allocate(theta(ym))
97  allocate(phi(xm))
98  call mpi_file_read(file_handle,theta,ym,mpi_double_precision,&
99  statuss,ierrmpi)
100  call mpi_file_read(file_handle,phi,xm,mpi_double_precision,&
101  statuss,ierrmpi)
102  call mpi_file_read(file_handle,b_r0,xm*ym,mpi_double_precision,&
103  statuss,ierrmpi)
104  call mpi_file_close(file_handle,ierrmpi)
105  print*,'nphi,ntheta',xm,ym
106  print*,'theta range:',minval(theta),maxval(theta)
107  print*,'phi range:',minval(phi),maxval(phi)
108  print*,'Brmax,Brmin',maxval(b_r0),minval(b_r0)
109  allocate(cfwm(ym))
110  call cfweights(ym,dcos(theta),cfwm)
111  allocate(flm(0:lmax,0:lmax))
112  call coef(b_r0,xm,ym,dcos(theta),dsin(theta),cfwm)
113  deallocate(b_r0)
114  deallocate(theta)
115  deallocate(phi)
116  amode=ior(mpi_mode_create,mpi_mode_wronly)
117  call mpi_file_open(mpi_comm_self,fharmcoef,amode, &
118  mpi_info_null,file_handle,ierrmpi)
119  call mpi_file_write(file_handle,lmax,1,mpi_integer,statuss,ierrmpi)
120  call mpi_file_write(file_handle,flm,(lmax+1)*(lmax+1),&
121  mpi_double_complex,statuss,ierrmpi)
122  call mpi_file_close(file_handle,ierrmpi)
123  endif
124  call mpi_barrier(icomm,ierrmpi)
125  if(npe>1) call mpi_bcast(lmax,1,mpi_integer,0,icomm,ierrmpi)
126  if(mype/=0) allocate(flm(0:lmax,0:lmax))
127  call mpi_barrier(icomm,ierrmpi)
128  if(npe>1) call mpi_bcast(flm,(lmax+1)*(lmax+1),mpi_double_complex,0,&
129  icomm,ierrmpi)
130  end if
131  if(mype==0) print*,'lmax=',lmax,'trunc=',trunc
132  nlarr=501
133  allocate(lmaxarray(nlarr))
134  allocate(xrg(nlarr))
135  lmaxarray=lmax
136  if(trunc) then
137  dxr=(r_s-r_0)/dble(nlarr-1)
138  do ir=1,nlarr
139  xrg(ir)=dxr*dble(ir-1)+r_0
140  do il=0,lmax
141  xrl=xrg(ir)**il
142  if(xrl > 1.d6) then
143  lmaxarray(ir)=il
144  exit
145  end if
146  end do
147  end do
148  endif
149  ! calculate global Alm Blm Rlm
150  allocate(alm(0:lmax,0:lmax))
151  allocate(blm(0:lmax,0:lmax))
152  allocate(rlm(0:lmax,0:lmax))
153  alm=(0.d0,0.d0)
154  blm=(0.d0,0.d0)
155  do l=0,lmax
156  do m=0,l
157  rsl=r_s**(-(2*l+1))
158  rlm(l,m)=dsqrt(dble(l**2-m**2)/dble(4*l**2-1))
159  blm(l,m)=-flm(l,m)/(1.d0+dble(l)+dble(l)*rsl)
160  alm(l,m)=-rsl*blm(l,m)
161  end do
162  end do
163 
164  end subroutine harm_coef
165 
166  subroutine cfweights(ym,miu,cfwm)
168 
169  integer, intent(in) :: ym
170  double precision, intent(in) :: miu(ym)
171  double precision, intent(out) :: cfwm(ym)
172 
173  double precision,dimension(ym) :: Pl,Pm2,Pm1,Pprime,sintheta
174  double precision :: lr
175  integer :: l
176 
177  sintheta=dsqrt(1.d0-miu**2)
178 
179  pm2=1.d0
180  pm1=miu
181 
182  do l=2,ym-1
183  lr=1.d0/dble(l)
184  pl=(2.d0-lr)*pm1*miu-(1.d0-lr)*pm2
185  pm2=pm1
186  pm1=pl
187  end do
188 
189  pprime=(dble(ym)*pl)/sintheta**2
190  cfwm=2.d0/(sintheta*pprime)**2
191  cfwm=cfwm*(2.d0*dpi)
192 
193  end subroutine cfweights
194 
195  subroutine coef(b_r0,xm,ym,miu,mius,cfwm)
197 
198  integer, intent(in) :: xm,ym
199  double precision, intent(in) :: b_r0(xm,ym),cfwm(ym),miu(ym),mius(ym)
200 
201  double complex :: Bm(0:xm-1,0:ym-1)
202  double precision,dimension(xm) :: fftmr,fftmi
203  double precision,dimension(0:lmax) :: N_mm
204  double precision,dimension(ym) :: P_lm1,P_lm2,old_Pmm,P_l
205  double precision :: mr,lr,c1,c2
206  integer :: l,m,i,j,stat
207 
208  bm=(0.d0,0.d0)
209  do i=1,ym
210  fftmr=b_r0(:,i)/dble(xm)
211  fftmi=0.d0
212  call fft(fftmr,fftmi,xm,xm,xm,-1)
213  bm(:,i-1)=(fftmr+(0.d0,1.d0)*fftmi)
214  end do
215  n_mm(0)=1.d0/dsqrt(4.d0*dpi)
216  do m=1,lmax
217  n_mm(m)=-n_mm(m-1)*dsqrt(1.d0+1.d0/dble(2*m))
218  end do
219  !first do m=0
220  p_lm2=n_mm(0)
221  p_lm1=p_lm2*miu*dsqrt(3.d0)
222  !set l=0 m=0 term
223  flm(0,0)=sum(bm(0,:)*p_lm2*cfwm)
224  !set l=1 m=0 term
225  flm(1,0)=sum(bm(0,:)*p_lm1*cfwm)
226  do l=2,lmax
227  lr=dble(l)
228  c1=dsqrt(4.d0-1.d0/lr**2)
229  c2=-(1.d0-1.d0/lr)*dsqrt((2.d0*lr+1.d0)/(2.d0*lr-3.d0))
230  p_l=c1*miu*p_lm1+c2*p_lm2
231  !set m=0 term for all other l's
232  flm(l,0)=sum(bm(0,:)*p_l*cfwm)
233  p_lm2=p_lm1
234  p_lm1=p_l
235  end do
236 
237  !since only l modes from 0 to lmax are used
238  bm=2.d0*bm
239 
240  !now the rest of the m's
241  old_pmm=n_mm(0)
242  do m=1,lmax
243  p_lm2=old_pmm*mius*n_mm(m)/n_mm(m-1)
244  p_lm1=p_lm2*miu*dsqrt(dble(2*m+3))
245  !ACCURATE UP TO HERE
246  old_pmm=p_lm2
247  !set l=m mode
248  flm(m,m)=sum(bm(m,:)*p_lm2*cfwm)
249  !set l=m+1 mode
250  if(m<lmax) flm(m+1,m)=sum(bm(m,:)*p_lm1*cfwm)
251  mr=dble(m)
252  do l=m+2,lmax
253  lr=dble(l)
254  c1=dsqrt((4.d0*lr**2-1.d0)/(lr**2-mr**2))
255  c2=-dsqrt(((2.d0*lr+1.d0)*((lr-1.d0)**2-mr**2))/((2.d0*lr-3.d0)*(lr**2-&
256  mr**2)))
257  p_l=c1*miu*p_lm1+c2*p_lm2
258  flm(l,m)=sum(bm(m,:)*p_l*cfwm)
259  p_lm2=p_lm1
260  p_lm1=p_l
261  end do
262  end do
263 
264  end subroutine coef
265 {^ifthreed
266  subroutine pfss(ixI^L,ixO^L,Bpf,x)
268 
269  integer, intent(in) :: ixi^l,ixo^l
270  double precision, intent(in) :: x(ixi^s,1:ndim)
271  double precision, intent(out) :: bpf(ixi^s,1:ndir)
272 
273  double complex :: bt(0:lmax,0:lmax,ixomin1:ixomax1)
274  double precision :: phase(ixi^s,1:ndir),bpfiv(ixomin3:ixomax3,ixomin2:ixomax2)
275  double precision :: miu(ixomin2:ixomax2),mius(ixomin2:ixomax2),xr
276  integer :: l,m,ix^d,j,l1,l2,ntheta,nphi,ir,qlmax
277 
278  bt=(0.d0,0.d0)
279  nphi=ixomax3-ixomin3+1
280  ntheta=ixomax2-ixomin2+1
281  miu(ixomin2:ixomax2)=dcos(x(ixomin1,ixomax2:ixomin2:-1,ixomin3,2))
282  mius(ixomin2:ixomax2)=dsin(x(ixomin1,ixomax2:ixomin2:-1,ixomin3,2))
283  do ix1=ixomin1,ixomax1
284  xr=x(ix1,ixomin2,ixomin3,1)
285  if(trunc) then
286  do ir=1,size(lmaxarray)
287  if(xrg(ir)>=xr) exit
288  end do
289  if(ir>size(lmaxarray)) ir=size(lmaxarray)
290  qlmax=lmaxarray(ir)
291  else
292  qlmax=lmax
293  endif
294  !Calculate Br
295  do l=0,lmax
296  do m=0,l
297  bt(l,m,ix1)=alm(l,m)*dble(l)*xr**(l-1)-blm(l,m)*dble(l+1)*xr**(-l-2)
298  end do
299  enddo
300  call inv_sph_transform(bt(:,:,ix1),x(ixomin1,ixomin2,&
301  ixomin3:ixomax3,3),miu,mius,nphi,ntheta,bpfiv,qlmax)
302  do ix3=ixomin3,ixomax3
303  do ix2=ixomin2,ixomax2
304  bpf(ix1,ix2,ix3,1)=bpfiv(ix3,ixomax2-ix2+ixomin2)
305  enddo
306  enddo
307  !Calculate Btheta
308  do l=0,lmax
309  do m=0,l
310  if (l==0) then
311  bt(l,m,ix1)=-rlm(l+1,m)*dble(l+2)*&
312  (alm(l+1,m)*xr**l+blm(l+1,m)*xr**(-l-3))
313  else if (l>=1 .and. l<=lmax-1) then
314  bt(l,m,ix1)=rlm(l,m)*&
315  dble(l-1)*(alm(l-1,m)*xr**(l-2)+blm(l-1,m)*&
316  xr**(-l-1))-rlm(l+1,m)*dble(l+2)*&
317  (alm(l+1,m)*xr**l+blm(l+1,m)*xr**(-l-3))
318  else
319  bt(l,m,ix1)=rlm(l,m)*&
320  dble(l-1)*(alm(l-1,m)*xr**(l-2)+blm(l-1,m)*xr**(-l-1))
321  end if
322  end do
323  enddo
324  call inv_sph_transform(bt(:,:,ix1),x(ixomin1,ixomin2,&
325  ixomin3:ixomax3,3),miu,mius,nphi,ntheta,bpfiv,qlmax)
326  do ix3=ixomin3,ixomax3
327  do ix2=ixomin2,ixomax2
328  bpf(ix1,ix2,ix3,2)=bpfiv(ix3,ixomax2-ix2+ixomin2)/mius(&
329  ixomax2-ix2+ixomin2)
330  enddo
331  enddo
332 
333  !Calculate Bphi
334  do l=0,lmax
335  do m=0,l
336  bt(l,m,ix1)=(0.d0,1.d0)*m*(alm(l,m)*xr**(l-1)+blm(l,m)*xr**(-l-2))
337  end do
338  enddo
339  call inv_sph_transform(bt(:,:,ix1),x(ixomin1,ixomin2,&
340  ixomin3:ixomax3,3),miu,mius,nphi,ntheta,bpfiv,qlmax)
341  do ix3=ixomin3,ixomax3
342  do ix2=ixomin2,ixomax2
343  bpf(ix1,ix2,ix3,3)=bpfiv(ix3,ixomax2-ix2+ixomin2)/mius(&
344  ixomax2-ix2+ixomin2)
345  enddo
346  enddo
347  enddo
348  !Scalar Potential
349  ! Potlc(ix^D)=Alm(l,m)*x(ix^D,1)**l+Blm(l,m)*x(ix^D,1)**(-l-1)
350 
351  !do ix3=ixOmin3,ixOmax3
352  ! do ix2=ixOmin2,ixOmax2
353  ! print*,x(ix1,ixOmax2-ix2+ixOmin2,ix3,2)
354  ! print*,'miu==',miu(ixOmax2-ix2+ixOmin2)
355  ! enddo
356  !enddo
357 
358  end subroutine pfss
359 
360  subroutine inv_sph_transform(Bt,phi,miu,mius,nphi,ntheta,Bpf,qlmax)
362 
363  integer, intent(in) :: nphi,ntheta,qlmax
364  double complex, intent(in) :: Bt(0:lmax,0:lmax)
365  double precision, intent(in) :: phi(nphi),miu(ntheta),mius(ntheta)
366  double precision, intent(out) :: Bpf(nphi,ntheta)
367 
368  double precision,dimension(0:lmax,0:lmax) :: cp,phase,Bamp
369  double precision,dimension(ntheta) :: cp_1_0,cp_l_0,cp_lm1_0,cp_lm2_0,cp_m_m
370  double precision,dimension(ntheta) :: cp_1_m,cp_l_m,cp_lm1_m,cp_lm2_m,cp_mp1_m
371  double precision :: angpart(nphi)
372  double precision :: ld,md,c1,c2,cp_0_0
373  integer :: l,m,iph,ith
374 
375  bamp=abs(bt)
376 
377  phase=atan2(dimag(bt),dble(bt))
378 
379  bpf=0.d0
380  !take care of modes where m=0
381  cp_0_0=dsqrt(1.d0/(4.d0*dpi))
382  !start with l=m=0 mode
383  bpf=bpf+bamp(0,0)*dcos(phase(0,0))*cp_0_0
384 
385  !proceed with l=1 m=0 mode
386  cp_1_0=dsqrt(3.d0)*miu*cp_0_0
387  do iph=1,nphi
388  bpf(iph,:)=bpf(iph,:)+bamp(1,0)*dcos(phase(1,0))*cp_1_0
389  enddo
390 
391  !proceed with l modes for which m=0
392  cp_lm1_0=cp_0_0
393  cp_l_0=cp_1_0
394  do l=2,qlmax
395  ld=dble(l)
396  cp_lm2_0=cp_lm1_0
397  cp_lm1_0=cp_l_0
398  c1=dsqrt(4.d0*ld**2-1.d0)/ld
399  c2=dsqrt((2.d0*ld+1.d0)/(2.d0*ld-3.d0))*(ld-1.d0)/ld
400  cp_l_0=c1*miu*cp_lm1_0-c2*cp_lm2_0
401  do iph=1,nphi
402  bpf(iph,:)=bpf(iph,:)+bamp(l,0)*dcos(phase(l,0))*cp_l_0
403  enddo
404  enddo
405 
406  !loop through m's for m>0 and then loop through l's for each m
407  cp_m_m=cp_0_0
408  do m=1,qlmax
409  md=dble(m)
410  !first do l=m modes
411  cp_m_m=-dsqrt(1.d0+1.d0/(2.d0*md))*mius*cp_m_m
412  do iph=1,nphi
413  angpart(iph)=dcos(md*phi(iph)+phase(m,m))
414  end do
415  do ith=1,ntheta
416  do iph=1,nphi
417  bpf(iph,ith)=bpf(iph,ith)+bamp(m,m)*angpart(iph)*cp_m_m(ith)
418  enddo
419  enddo
420 
421  !proceed with l=m+1 modes
422  if(qlmax>=m+1) then
423  cp_mp1_m=dsqrt(2.d0*md+3.d0)*miu*cp_m_m
424  angpart=dcos(md*phi+phase(m+1,m))
425  do ith=1,ntheta
426  do iph=1,nphi
427  bpf(iph,ith)=bpf(iph,ith)+bamp(m+1,m)*angpart(iph)*cp_mp1_m(ith)
428  enddo
429  enddo
430  endif
431 
432  !finish with the rest l
433  if(qlmax>=m+2) then
434  cp_lm1_m=cp_m_m
435  cp_l_m=cp_mp1_m
436  do l=m+2,qlmax
437  ld=dble(l)
438  cp_lm2_m=cp_lm1_m
439  cp_lm1_m=cp_l_m
440  c1=dsqrt((4.d0*ld**2-1.d0)/(ld**2-md**2))
441  c2=dsqrt((2.d0*ld+1.d0)*((ld-1.d0)**2-md**2)/(2.d0*ld-3.d0)/(ld**2-md**2))
442  cp_l_m=c1*miu*cp_lm1_m-c2*cp_lm2_m
443  angpart=dcos(md*phi+phase(l,m))
444  do ith=1,ntheta
445  do iph=1,nphi
446  bpf(iph,ith)=bpf(iph,ith)+bamp(l,m)*angpart(iph)*cp_l_m(ith)
447  enddo
448  enddo
449  enddo
450  endif
451  enddo
452 
453  end subroutine inv_sph_transform
454 }
455  subroutine fft(a,b,ntot,n,nspan,isn)
456  ! multivariate complex fourier transform, computed in place
457  ! using mixed-radix fast fourier transform algorithm.
458  ! by r. c. singleton, stanford research institute, sept. 1968
459  ! arrays a and b originally hold the real and imaginary
460  ! components of the data, and return the real and
461  ! imaginary components of the resulting fourier coefficients.
462  ! multivariate data is indexed according to the fortran
463  ! array element successor function, without limit
464  ! on the number of implied multiple subscripts.
465  ! the subroutine is called once for each variate.
466  ! the calls for a multivariate transform may be in any order.
467  ! ntot is the total number of complex data values.
468  ! n is the dimension of the current variable.
469  ! nspan/n is the spacing of consecutive data values
470  ! while indexing the current variable.
471  ! the sign of isn determines the sign of the complex
472  ! exponential, and the magnitude of isn is normally one.
473  ! a tri-variate transform with a(n1,n2,n3), b(n1,n2,n3)
474  ! is computed by
475  ! call fft(a,b,n1*n2*n3,n1,n1,1)
476  ! call fft(a,b,n1*n2*n3,n2,n1*n2,1)
477  ! call fft(a,b,n1*n2*n3,n3,n1*n2*n3,1)
478  ! for a single-variate transform,
479  ! ntot = n = nspan = (number of complex data values), e.g.
480  ! call fft(a,b,n,n,n,1)
481  ! the data can alternatively be stored in a single complex array c
482  ! in standard fortran fashion, i.e. alternating real and imaginary
483  ! parts. then with most fortran compilers, the complex array c can
484  ! be equivalenced to a real array a, the magnitude of isn changed
485  ! to two to give correct indexing increment, and a(1) and a(2) used
486  ! to pass the initial addresses for the sequences of real and
487  ! imaginary values, e.g.
488  ! complex c(ntot)
489  ! real a(2*ntot)
490  ! equivalence (c(1),a(1))
491  ! call fft(a(1),a(2),ntot,n,nspan,2)
492  ! arrays at(maxf), ck(maxf), bt(maxf), sk(maxf), and np(maxp)
493  ! are used for temporary storage. if the available storage
494  ! is insufficient, the program is terminated by a stop.
495  ! maxf must be .ge. the maximum prime factor of n.
496  ! maxp must be .gt. the number of prime factors of n.
497  ! in addition, if the square-free portion k of n has two or
498  ! more prime factors, then maxp must be .ge. k-1.
499  double precision :: a(:),b(:)
500  ! array storage in nfac for a maximum of 15 prime factors of n.
501  ! if n has more than one square-free factor, the product of the
502  ! square-free factors must be .le. 210
503  dimension nfac(11),np(209)
504  ! array storage for maximum prime factor of 23
505  dimension at(23),ck(23),bt(23),sk(23)
506  integer :: i,ii,maxp,maxf,n,inc,isn,nt,ntot,ks,nspan,kspan,nn,jc,jf,m
507  integer :: k,j,jj,nfac,kt,np,kk,k1,k2,k3,k4,kspnn
508  double precision :: c72,s72,s120,rad,radf,sd,cd,ak,bk,c1
509  double precision :: s1,aj,bj,akp,ajp,ajm,akm,bkp,bkm,bjp,bjm,aa
510  double precision :: bb,sk,ck,at,bt,s3,c3,s2,c2
511  equivalence(i,ii)
512 
513  ! the following two constants should agree with the array dimensions.
514  maxp=209
515  ! Date: Wed, 9 Aug 1995 09:38:49 -0400
516  ! From: ldm@apollo.numis.nwu.edu
517  maxf=23
518  s3=0.d0
519  s2=0.d0
520  c3=0.d0
521  c2=0.d0
522  if(n .lt. 2) return
523  inc=isn
524  c72=0.30901699437494742d0
525  s72=0.95105651629515357d0
526  s120=0.86602540378443865d0
527  rad=6.2831853071796d0
528  if(isn .ge. 0) go to 10
529  s72=-s72
530  s120=-s120
531  rad=-rad
532  inc=-inc
533  10 nt=inc*ntot
534  ks=inc*nspan
535  kspan=ks
536  nn=nt-inc
537  jc=ks/n
538  radf=rad*dble(jc)*0.5d0
539  i=0
540  jf=0
541  ! determine the factors of n
542  m=0
543  k=n
544  go to 20
545  15 m=m+1
546  nfac(m)=4
547  k=k/16
548  20 if(k-(k/16)*16 .eq. 0) go to 15
549  j=3
550  jj=9
551  go to 30
552  25 m=m+1
553  nfac(m)=j
554  k=k/jj
555  30 if(mod(k,jj) .eq. 0) go to 25
556  j=j+2
557  jj=j**2
558  if(jj .le. k) go to 30
559  if(k .gt. 4) go to 40
560  kt=m
561  nfac(m+1)=k
562  if(k .ne. 1) m=m+1
563  go to 80
564  40 if(k-(k/4)*4 .ne. 0) go to 50
565  m=m+1
566  nfac(m)=2
567  k=k/4
568  50 kt=m
569  j=2
570  60 if(mod(k,j) .ne. 0) go to 70
571  m=m+1
572  nfac(m)=j
573  k=k/j
574  70 j=((j+1)/2)*2+1
575  if(j .le. k) go to 60
576  80 if(kt .eq. 0) go to 100
577  j=kt
578  90 m=m+1
579  nfac(m)=nfac(j)
580  j=j-1
581  if(j .ne. 0) go to 90
582  ! compute fourier transform
583  100 sd=radf/dble(kspan)
584  cd=2.d0*dsin(sd)**2
585  sd=dsin(sd+sd)
586  kk=1
587  i=i+1
588  if(nfac(i) .ne. 2) go to 400
589  ! transform for factor of 2 (including rotation factor)
590  kspan=kspan/2
591  k1=kspan+2
592  210 k2=kk+kspan
593  ak=a(k2)
594  bk=b(k2)
595  a(k2)=a(kk)-ak
596  b(k2)=b(kk)-bk
597  a(kk)=a(kk)+ak
598  b(kk)=b(kk)+bk
599  kk=k2+kspan
600  if(kk .le. nn) go to 210
601  kk=kk-nn
602  if(kk .le. jc) go to 210
603  if(kk .gt. kspan) go to 800
604  220 c1=1.d0-cd
605  s1=sd
606  230 k2=kk+kspan
607  ak=a(kk)-a(k2)
608  bk=b(kk)-b(k2)
609  a(kk)=a(kk)+a(k2)
610  b(kk)=b(kk)+b(k2)
611  a(k2)=c1*ak-s1*bk
612  b(k2)=s1*ak+c1*bk
613  kk=k2+kspan
614  if(kk .lt. nt) go to 230
615  k2=kk-nt
616  c1=-c1
617  kk=k1-k2
618  if(kk .gt. k2) go to 230
619  ak=c1-(cd*c1+sd*s1)
620  s1=(sd*c1-cd*s1)+s1
621  c1=2.d0-(ak**2+s1**2)
622  s1=c1*s1
623  c1=c1*ak
624  kk=kk+jc
625  if(kk .lt. k2) go to 230
626  k1=k1+inc+inc
627  kk=(k1-kspan)/2+jc
628  if(kk .le. jc+jc) go to 220
629  go to 100
630  ! transform for factor of 3 (optional code)
631  320 k1=kk+kspan
632  k2=k1+kspan
633  ak=a(kk)
634  bk=b(kk)
635  aj=a(k1)+a(k2)
636  bj=b(k1)+b(k2)
637  a(kk)=ak+aj
638  b(kk)=bk+bj
639  ak=-0.5d0*aj+ak
640  bk=-0.5d0*bj+bk
641  aj=(a(k1)-a(k2))*s120
642  bj=(b(k1)-b(k2))*s120
643  a(k1)=ak-bj
644  b(k1)=bk+aj
645  a(k2)=ak+bj
646  b(k2)=bk-aj
647  kk=k2+kspan
648  if(kk .lt. nn) go to 320
649  kk=kk-nn
650  if(kk .le. kspan) go to 320
651  go to 700
652  ! transform for factor of 4
653  400 if(nfac(i) .ne. 4) go to 600
654  kspnn=kspan
655  kspan=kspan/4
656  410 c1=1.d0
657  s1=0.d0
658  420 k1=kk+kspan
659  k2=k1+kspan
660  k3=k2+kspan
661  akp=a(kk)+a(k2)
662  akm=a(kk)-a(k2)
663  ajp=a(k1)+a(k3)
664  ajm=a(k1)-a(k3)
665  a(kk)=akp+ajp
666  ajp=akp-ajp
667  bkp=b(kk)+b(k2)
668  bkm=b(kk)-b(k2)
669  bjp=b(k1)+b(k3)
670  bjm=b(k1)-b(k3)
671  b(kk)=bkp+bjp
672  bjp=bkp-bjp
673  if(isn .lt. 0) go to 450
674  akp=akm-bjm
675  akm=akm+bjm
676  bkp=bkm+ajm
677  bkm=bkm-ajm
678  if(s1 .eq. 0.d0) go to 460
679  430 a(k1)=akp*c1-bkp*s1
680  b(k1)=akp*s1+bkp*c1
681  a(k2)=ajp*c2-bjp*s2
682  b(k2)=ajp*s2+bjp*c2
683  a(k3)=akm*c3-bkm*s3
684  b(k3)=akm*s3+bkm*c3
685  kk=k3+kspan
686  if(kk .le. nt) go to 420
687  440 c2=c1-(cd*c1+sd*s1)
688  s1=(sd*c1-cd*s1)+s1
689  c1=2.d0-(c2**2+s1**2)
690  s1=c1*s1
691  c1=c1*c2
692  c2=c1**2-s1**2
693  s2=2.d0*c1*s1
694  c3=c2*c1-s2*s1
695  s3=c2*s1+s2*c1
696  kk=kk-nt+jc
697  if(kk .le. kspan) go to 420
698  kk=kk-kspan+inc
699  if(kk .le. jc) go to 410
700  if(kspan .eq. jc) go to 800
701  go to 100
702  450 akp=akm+bjm
703  akm=akm-bjm
704  bkp=bkm-ajm
705  bkm=bkm+ajm
706  if(s1 .ne. 0) go to 430
707  460 a(k1)=akp
708  b(k1)=bkp
709  a(k2)=ajp
710  b(k2)=bjp
711  a(k3)=akm
712  b(k3)=bkm
713  kk=k3+kspan
714  if(kk .le. nt) go to 420
715  go to 440
716  ! transform for factor of 5 (optional code)
717  510 c2=c72**2-s72**2
718  s2=2.d0*c72*s72
719  520 k1=kk+kspan
720  k2=k1+kspan
721  k3=k2+kspan
722  k4=k3+kspan
723  akp=a(k1)+a(k4)
724  akm=a(k1)-a(k4)
725  bkp=b(k1)+b(k4)
726  bkm=b(k1)-b(k4)
727  ajp=a(k2)+a(k3)
728  ajm=a(k2)-a(k3)
729  bjp=b(k2)+b(k3)
730  bjm=b(k2)-b(k3)
731  aa=a(kk)
732  bb=b(kk)
733  a(kk)=aa+akp+ajp
734  b(kk)=bb+bkp+bjp
735  ak=akp*c72+ajp*c2+aa
736  bk=bkp*c72+bjp*c2+bb
737  aj=akm*s72+ajm*s2
738  bj=bkm*s72+bjm*s2
739  a(k1)=ak-bj
740  a(k4)=ak+bj
741  b(k1)=bk+aj
742  b(k4)=bk-aj
743  ak=akp*c2+ajp*c72+aa
744  bk=bkp*c2+bjp*c72+bb
745  aj=akm*s2-ajm*s72
746  bj=bkm*s2-bjm*s72
747  a(k2)=ak-bj
748  a(k3)=ak+bj
749  b(k2)=bk+aj
750  b(k3)=bk-aj
751  kk=k4+kspan
752  if(kk .lt. nn) go to 520
753  kk=kk-nn
754  if(kk .le. kspan) go to 520
755  go to 700
756  ! transform for odd factors
757  600 k=nfac(i)
758  kspnn=kspan
759  kspan=kspan/k
760  if(k .eq. 3) go to 320
761  if(k .eq. 5) go to 510
762  if(k .eq. jf) go to 640
763  jf=k
764  s1=rad/dble(k)
765  c1=dcos(s1)
766  s1=dsin(s1)
767  if(jf .gt. maxf) go to 998
768  ck(jf)=1.d0
769  sk(jf)=0.d0
770  j=1
771  630 ck(j)=ck(k)*c1+sk(k)*s1
772  sk(j)=ck(k)*s1-sk(k)*c1
773  k=k-1
774  ck(k)=ck(j)
775  sk(k)=-sk(j)
776  j=j+1
777  if(j .lt. k) go to 630
778  640 k1=kk
779  k2=kk+kspnn
780  aa=a(kk)
781  bb=b(kk)
782  ak=aa
783  bk=bb
784  j=1
785  k1=k1+kspan
786  650 k2=k2-kspan
787  j=j+1
788  at(j)=a(k1)+a(k2)
789  ak=at(j)+ak
790  bt(j)=b(k1)+b(k2)
791  bk=bt(j)+bk
792  j=j+1
793  at(j)=a(k1)-a(k2)
794  bt(j)=b(k1)-b(k2)
795  k1=k1+kspan
796  if(k1 .lt. k2) go to 650
797  a(kk)=ak
798  b(kk)=bk
799  k1=kk
800  k2=kk+kspnn
801  j=1
802  660 k1=k1+kspan
803  k2=k2-kspan
804  jj=j
805  ak=aa
806  bk=bb
807  aj=0.d0
808  bj=0.d0
809  k=1
810  670 k=k+1
811  ak=at(k)*ck(jj)+ak
812  bk=bt(k)*ck(jj)+bk
813  k=k+1
814  aj=at(k)*sk(jj)+aj
815  bj=bt(k)*sk(jj)+bj
816  jj=jj+j
817  if(jj .gt. jf) jj=jj-jf
818  if(k .lt. jf) go to 670
819  k=jf-j
820  a(k1)=ak-bj
821  b(k1)=bk+aj
822  a(k2)=ak+bj
823  b(k2)=bk-aj
824  j=j+1
825  if(j .lt. k) go to 660
826  kk=kk+kspnn
827  if(kk .le. nn) go to 640
828  kk=kk-nn
829  if(kk .le. kspan) go to 640
830  ! multiply by rotation factor (except for factors of 2 and 4)
831  700 if(i .eq. m) go to 800
832  kk=jc+1
833  710 c2=1.d0-cd
834  s1=sd
835  720 c1=c2
836  s2=s1
837  kk=kk+kspan
838  730 ak=a(kk)
839  a(kk)=c2*ak-s2*b(kk)
840  b(kk)=s2*ak+c2*b(kk)
841  kk=kk+kspnn
842  if(kk .le. nt) go to 730
843  ak=s1*s2
844  s2=s1*c2+c1*s2
845  c2=c1*c2-ak
846  kk=kk-nt+kspan
847  if(kk .le. kspnn) go to 730
848  c2=c1-(cd*c1+sd*s1)
849  s1=s1+(sd*c1-cd*s1)
850  c1=2.d0-(c2**2+s1**2)
851  s1=c1*s1
852  c2=c1*c2
853  kk=kk-kspnn+jc
854  if(kk .le. kspan) go to 720
855  kk=kk-kspan+jc+inc
856  if(kk .le. jc+jc) go to 710
857  go to 100
858  ! permute the results to normal order---done in two stages
859  ! permutation for square factors of n
860  800 np(1)=ks
861  if(kt .eq. 0) go to 890
862  k=kt+kt+1
863  if(m .lt. k) k=k-1
864  j=1
865  np(k+1)=jc
866  810 np(j+1)=np(j)/nfac(j)
867  np(k)=np(k+1)*nfac(j)
868  j=j+1
869  k=k-1
870  if(j .lt. k) go to 810
871  k3=np(k+1)
872  kspan=np(2)
873  kk=jc+1
874  k2=kspan+1
875  j=1
876  if(n .ne. ntot) go to 850
877  ! permutation for single-variate transform (optional code)
878  820 ak=a(kk)
879  a(kk)=a(k2)
880  a(k2)=ak
881  bk=b(kk)
882  b(kk)=b(k2)
883  b(k2)=bk
884  kk=kk+inc
885  k2=kspan+k2
886  if(k2 .lt. ks) go to 820
887  830 k2=k2-np(j)
888  j=j+1
889  k2=np(j+1)+k2
890  if(k2 .gt. np(j)) go to 830
891  j=1
892  840 if(kk .lt. k2) go to 820
893  kk=kk+inc
894  k2=kspan+k2
895  if(k2 .lt. ks) go to 840
896  if(kk .lt. ks) go to 830
897  jc=k3
898  go to 890
899  ! permutation for multivariate transform
900  850 k=kk+jc
901  860 ak=a(kk)
902  a(kk)=a(k2)
903  a(k2)=ak
904  bk=b(kk)
905  b(kk)=b(k2)
906  b(k2)=bk
907  kk=kk+inc
908  k2=k2+inc
909  if(kk .lt. k) go to 860
910  kk=kk+ks-jc
911  k2=k2+ks-jc
912  if(kk .lt. nt) go to 850
913  k2=k2-nt+kspan
914  kk=kk-nt+jc
915  if(k2 .lt. ks) go to 850
916  870 k2=k2-np(j)
917  j=j+1
918  k2=np(j+1)+k2
919  if(k2 .gt. np(j)) go to 870
920  j=1
921  880 if(kk .lt. k2) go to 850
922  kk=kk+jc
923  k2=kspan+k2
924  if(k2 .lt. ks) go to 880
925  if(kk .lt. ks) go to 870
926  jc=k3
927  890 if(2*kt+1 .ge. m) return
928  kspnn=np(kt+1)
929  ! permutation for square-free factors of n
930  j=m-kt
931  nfac(j+1)=1
932  900 nfac(j)=nfac(j)*nfac(j+1)
933  j=j-1
934  if(j .ne. kt) go to 900
935  kt=kt+1
936  nn=nfac(kt)-1
937  if(nn .gt. maxp) go to 998
938  jj=0
939  j=0
940  go to 906
941  902 jj=jj-k2
942  k2=kk
943  k=k+1
944  kk=nfac(k)
945  904 jj=kk+jj
946  if(jj .ge. k2) go to 902
947  np(j)=jj
948  906 k2=nfac(kt)
949  k=kt+1
950  kk=nfac(k)
951  j=j+1
952  if(j .le. nn) go to 904
953  ! determine the permutation cycles of length greater than 1
954  j=0
955  go to 914
956  910 k=kk
957  kk=np(k)
958  np(k)=-kk
959  if(kk .ne. j) go to 910
960  k3=kk
961  914 j=j+1
962  kk=np(j)
963  if(kk .lt. 0) go to 914
964  if(kk .ne. j) go to 910
965  np(j)=-j
966  if(j .ne. nn) go to 914
967  maxf=inc*maxf
968  ! reorder a and b, following the permutation cycles
969  go to 950
970  924 j=j-1
971  if(np(j) .lt. 0) go to 924
972  jj=jc
973  926 kspan=jj
974  if(jj .gt. maxf) kspan=maxf
975  jj=jj-kspan
976  k=np(j)
977  kk=jc*k+ii+jj
978  k1=kk+kspan
979  k2=0
980  928 k2=k2+1
981  at(k2)=a(k1)
982  bt(k2)=b(k1)
983  k1=k1-inc
984  if(k1 .ne. kk) go to 928
985  932 k1=kk+kspan
986  k2=k1-jc*(k+np(k))
987  k=-np(k)
988  936 a(k1)=a(k2)
989  b(k1)=b(k2)
990  k1=k1-inc
991  k2=k2-inc
992  if(k1 .ne. kk) go to 936
993  kk=k2
994  if(k .ne. j) go to 932
995  k1=kk+kspan
996  k2=0
997  940 k2=k2+1
998  a(k1)=at(k2)
999  b(k1)=bt(k2)
1000  k1=k1-inc
1001  if(k1 .ne. kk) go to 940
1002  if(jj .ne. 0) go to 926
1003  if(j .ne. 1) go to 924
1004  950 j=k3+1
1005  nt=nt-kspnn
1006  ii=nt-inc+1
1007  if(nt .ge. 0) go to 924
1008  return
1009  ! error finish, insufficient array storage
1010  998 isn=0
1011  print 999
1012  stop
1013  999 format(44h0array bounds exceeded within subroutine fft)
1014  end subroutine fft
1015 
1016 end module mod_pfss
subroutine mpistop(message)
Exit MPI-AMRVAC with an error message.
Definition: comm_lib.t:194
This module contains definitions of global parameters and variables and some generic functions/subrou...
integer, parameter ndim
Number of spatial dimensions for grid variables.
integer icomm
The MPI communicator.
integer mype
The rank of the current MPI task.
integer, dimension(:), allocatable, parameter d
integer ndir
Number of spatial dimensions (components) for vector variables.
integer ierrmpi
A global MPI error return code.
integer npe
The number of MPI tasks.
module mod_pfss.t – potential field source surface model PURPOSE : to extrapolate global potential ma...
Definition: mod_pfss.t:34
subroutine fft(a, b, ntot, n, nspan, isn)
Definition: mod_pfss.t:456
subroutine coef(b_r0, xm, ym, miu, mius, cfwm)
Definition: mod_pfss.t:196
subroutine, public pfss(ixIL, ixOL, Bpf, x)
Definition: mod_pfss.t:267
subroutine inv_sph_transform(Bt, phi, miu, mius, nphi, ntheta, Bpf, qlmax)
Definition: mod_pfss.t:361
double precision, public r_0
Definition: mod_pfss.t:40
subroutine cfweights(ym, miu, cfwm)
Definition: mod_pfss.t:167
integer, public lmax
Definition: mod_pfss.t:42
subroutine, public harm_coef(mapname)
Definition: mod_pfss.t:53
logical, public trunc
Definition: mod_pfss.t:43
double precision, public r_s
Definition: mod_pfss.t:40