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(:)
43 logical,
public ::
trunc=.false.
56 double precision,
allocatable :: b_r0(:,:)
57 double precision,
allocatable :: theta(:),phi(:),cfwm(:)
58 double precision :: rsl,xrl,dxr
59 integer :: xm,ym,
l,m,amode,file_handle,il,ir,nlarr,nsh
60 integer,
dimension(MPI_STATUS_SIZE) :: statuss
62 character(len=*) :: mapname
63 character(len=80) :: fharmcoef
65 fharmcoef=mapname//
'.coef'
66 inquire(file=fharmcoef, exist=aexist)
69 call mpi_file_open(mpi_comm_self,fharmcoef,mpi_mode_rdonly, &
70 mpi_info_null,file_handle,
ierrmpi)
71 call mpi_file_read(file_handle,
lmax,1,mpi_integer,statuss,
ierrmpi)
73 call mpi_file_read(file_handle,flm,(
lmax+1)*(
lmax+1),&
74 mpi_double_complex,statuss,
ierrmpi)
75 call mpi_file_close(file_handle,
ierrmpi)
85 inquire(file=mapname,exist=aexist)
87 if(
mype==0)
write(*,
'(2a)')
"can not find file:",mapname
88 call mpistop(
"no input magnetogram found")
90 call mpi_file_open(mpi_comm_self,mapname,mpi_mode_rdonly,mpi_info_null,&
92 call mpi_file_read(file_handle,xm,1,mpi_integer,statuss,
ierrmpi)
93 call mpi_file_read(file_handle,ym,1,mpi_integer,statuss,
ierrmpi)
99 call mpi_file_read(file_handle,theta,ym,mpi_double_precision,&
101 call mpi_file_read(file_handle,phi,xm,mpi_double_precision,&
103 call mpi_file_read(file_handle,b_r0,xm*ym,mpi_double_precision,&
105 call mpi_file_close(file_handle,
ierrmpi)
106 print*,
'nphi,ntheta',xm,ym
107 print*,
'theta range:',minval(theta),maxval(theta)
108 print*,
'phi range:',minval(phi),maxval(phi)
109 print*,
'Brmax,Brmin',maxval(b_r0),minval(b_r0)
111 call cfweights(ym,dcos(theta),cfwm)
113 call coef(b_r0,xm,ym,dcos(theta),dsin(theta),cfwm)
117 amode=ior(mpi_mode_create,mpi_mode_wronly)
118 call mpi_file_open(mpi_comm_self,fharmcoef,amode, &
119 mpi_info_null,file_handle,
ierrmpi)
120 call mpi_file_write(file_handle,
lmax,1,mpi_integer,statuss,
ierrmpi)
121 call mpi_file_write(file_handle,flm,(
lmax+1)*(
lmax+1),&
122 mpi_double_complex,statuss,
ierrmpi)
123 call mpi_file_close(file_handle,
ierrmpi)
129 if(
npe>1)
call mpi_bcast(flm,(
lmax+1)*(
lmax+1),mpi_double_complex,0,&
134 allocate(lmaxarray(nlarr))
138 dxr=(
r_s-
r_0)/dble(nlarr-1)
140 xrg(ir)=dxr*dble(ir-1)+
r_0
159 rlm(
l,m)=dsqrt(dble(
l**2-m**2)/dble(4*
l**2-1))
160 blm(
l,m)=-flm(
l,m)/(1.d0+dble(
l)+dble(
l)*rsl)
161 alm(
l,m)=-rsl*blm(
l,m)
167 subroutine cfweights(ym,miu,cfwm)
170 integer,
intent(in) :: ym
171 double precision,
intent(in) :: miu(ym)
172 double precision,
intent(out) :: cfwm(ym)
174 double precision,
dimension(ym) :: pl,pm2,pm1,pprime,sintheta
175 double precision :: lr
178 sintheta=dsqrt(1.d0-miu**2)
185 pl=(2.d0-lr)*pm1*miu-(1.d0-lr)*pm2
190 pprime=(dble(ym)*pl)/sintheta**2
191 cfwm=2.d0/(sintheta*pprime)**2
194 end subroutine cfweights
196 subroutine coef(b_r0,xm,ym,miu,mius,cfwm)
199 integer,
intent(in) :: xm,ym
200 double precision,
intent(in) :: b_r0(xm,ym),cfwm(ym),miu(ym),mius(ym)
202 double complex :: bm(0:xm-1,0:ym-1)
203 double precision,
dimension(xm) :: fftmr,fftmi
204 double precision,
dimension(0:lmax) :: n_mm
205 double precision,
dimension(ym) :: p_lm1,p_lm2,old_pmm,p_l
206 double precision :: mr,lr,c1,c2
207 integer ::
l,m,i,j,stat
211 fftmr=b_r0(:,i)/dble(xm)
213 call fft(fftmr,fftmi,xm,xm,xm,-1)
214 bm(:,i-1)=(fftmr+(0.d0,1.d0)*fftmi)
216 n_mm(0)=1.d0/dsqrt(4.d0*dpi)
218 n_mm(m)=-n_mm(m-1)*dsqrt(1.d0+1.d0/dble(2*m))
222 p_lm1=p_lm2*miu*dsqrt(3.d0)
224 flm(0,0)=sum(bm(0,:)*p_lm2*cfwm)
226 flm(1,0)=sum(bm(0,:)*p_lm1*cfwm)
229 c1=dsqrt(4.d0-1.d0/lr**2)
230 c2=-(1.d0-1.d0/lr)*dsqrt((2.d0*lr+1.d0)/(2.d0*lr-3.d0))
231 p_l=c1*miu*p_lm1+c2*p_lm2
233 flm(
l,0)=sum(bm(0,:)*p_l*cfwm)
244 p_lm2=old_pmm*mius*n_mm(m)/n_mm(m-1)
245 p_lm1=p_lm2*miu*dsqrt(dble(2*m+3))
249 flm(m,m)=sum(bm(m,:)*p_lm2*cfwm)
251 if(m<
lmax) flm(m+1,m)=sum(bm(m,:)*p_lm1*cfwm)
255 c1=dsqrt((4.d0*lr**2-1.d0)/(lr**2-mr**2))
256 c2=-dsqrt(((2.d0*lr+1.d0)*((lr-1.d0)**2-mr**2))/((2.d0*lr-3.d0)*(lr**2-&
258 p_l=c1*miu*p_lm1+c2*p_lm2
259 flm(
l,m)=sum(bm(m,:)*p_l*cfwm)
267 subroutine pfss(ixI^L,ixO^L,Bpf,x)
270 integer,
intent(in) :: ixi^
l,ixo^
l
271 double precision,
intent(in) :: x(ixi^s,1:
ndim)
272 double precision,
intent(out) :: bpf(ixi^s,1:
ndir)
274 double complex :: bt(0:
lmax,0:
lmax,ixomin1:ixomax1)
275 double precision :: phase(ixi^s,1:
ndir),bpfiv(ixomin3:ixomax3,ixomin2:ixomax2)
276 double precision :: miu(ixomin2:ixomax2),mius(ixomin2:ixomax2),xr
277 double precision :: tmp(ixomin2:ixomax2)
278 integer ::
l,m,ix^
d,j,l1,l2,ntheta,nphi,ir,qlmax
281 nphi=ixomax3-ixomin3+1
282 ntheta=ixomax2-ixomin2+1
283 tmp(ixomin2:ixomax2)=x(ixomin1,ixomax2:ixomin2:-1,ixomin3,2)
284 miu(ixomin2:ixomax2)=dcos(tmp(ixomin2:ixomax2))
285 mius(ixomin2:ixomax2)=dsin(tmp(ixomin2:ixomax2))
286 do ix1=ixomin1,ixomax1
287 xr=x(ix1,ixomin2,ixomin3,1)
289 do ir=1,
size(lmaxarray)
292 if(ir>
size(lmaxarray)) ir=
size(lmaxarray)
300 bt(
l,m,ix1)=alm(
l,m)*dble(
l)*xr**(
l-1)-blm(
l,m)*dble(
l+1)*xr**(-
l-2)
303 call inv_sph_transform(bt(:,:,ix1),x(ixomin1,ixomin2,&
304 ixomin3:ixomax3,3),miu,mius,nphi,ntheta,bpfiv,qlmax)
305 do ix3=ixomin3,ixomax3
306 do ix2=ixomin2,ixomax2
307 bpf(ix1,ix2,ix3,1)=bpfiv(ix3,ixomax2-ix2+ixomin2)
314 bt(
l,m,ix1)=-rlm(
l+1,m)*dble(
l+2)*&
315 (alm(
l+1,m)*xr**
l+blm(
l+1,m)*xr**(-
l-3))
316 else if (
l>=1 .and.
l<=
lmax-1)
then
317 bt(
l,m,ix1)=rlm(
l,m)*&
318 dble(
l-1)*(alm(
l-1,m)*xr**(
l-2)+blm(
l-1,m)*&
319 xr**(-
l-1))-rlm(
l+1,m)*dble(
l+2)*&
320 (alm(
l+1,m)*xr**
l+blm(
l+1,m)*xr**(-
l-3))
322 bt(
l,m,ix1)=rlm(
l,m)*&
323 dble(
l-1)*(alm(
l-1,m)*xr**(
l-2)+blm(
l-1,m)*xr**(-
l-1))
327 call inv_sph_transform(bt(:,:,ix1),x(ixomin1,ixomin2,&
328 ixomin3:ixomax3,3),miu,mius,nphi,ntheta,bpfiv,qlmax)
329 do ix3=ixomin3,ixomax3
330 do ix2=ixomin2,ixomax2
331 bpf(ix1,ix2,ix3,2)=bpfiv(ix3,ixomax2-ix2+ixomin2)/mius(&
339 bt(
l,m,ix1)=(0.d0,1.d0)*m*(alm(
l,m)*xr**(
l-1)+blm(
l,m)*xr**(-
l-2))
342 call inv_sph_transform(bt(:,:,ix1),x(ixomin1,ixomin2,&
343 ixomin3:ixomax3,3),miu,mius,nphi,ntheta,bpfiv,qlmax)
344 do ix3=ixomin3,ixomax3
345 do ix2=ixomin2,ixomax2
346 bpf(ix1,ix2,ix3,3)=bpfiv(ix3,ixomax2-ix2+ixomin2)/mius(&
363 subroutine inv_sph_transform(Bt,phi,miu,mius,nphi,ntheta,Bpf,qlmax)
366 integer,
intent(in) :: nphi,ntheta,qlmax
367 double complex,
intent(in) :: bt(0:
lmax,0:
lmax)
368 double precision,
intent(in) :: phi(nphi),miu(ntheta),mius(ntheta)
369 double precision,
intent(out) :: bpf(nphi,ntheta)
371 double precision,
dimension(0:lmax,0:lmax) :: cp,phase,bamp
372 double precision,
dimension(ntheta) :: cp_1_0,cp_l_0,cp_lm1_0,cp_lm2_0,cp_m_m
373 double precision,
dimension(ntheta) :: cp_1_m,cp_l_m,cp_lm1_m,cp_lm2_m,cp_mp1_m
374 double precision :: angpart(nphi)
375 double precision :: ld,md,c1,c2,cp_0_0
376 integer ::
l,m,iph,ith
380 phase=atan2(dimag(bt),dble(bt))
384 cp_0_0=dsqrt(1.d0/(4.d0*dpi))
386 bpf=bpf+bamp(0,0)*dcos(phase(0,0))*cp_0_0
389 cp_1_0=dsqrt(3.d0)*miu*cp_0_0
391 bpf(iph,:)=bpf(iph,:)+bamp(1,0)*dcos(phase(1,0))*cp_1_0
401 c1=dsqrt(4.d0*ld**2-1.d0)/ld
402 c2=dsqrt((2.d0*ld+1.d0)/(2.d0*ld-3.d0))*(ld-1.d0)/ld
403 cp_l_0=c1*miu*cp_lm1_0-c2*cp_lm2_0
405 bpf(iph,:)=bpf(iph,:)+bamp(
l,0)*dcos(phase(
l,0))*cp_l_0
414 cp_m_m=-dsqrt(1.d0+1.d0/(2.d0*md))*mius*cp_m_m
416 angpart(iph)=dcos(md*phi(iph)+phase(m,m))
420 bpf(iph,ith)=bpf(iph,ith)+bamp(m,m)*angpart(iph)*cp_m_m(ith)
426 cp_mp1_m=dsqrt(2.d0*md+3.d0)*miu*cp_m_m
427 angpart=dcos(md*phi+phase(m+1,m))
430 bpf(iph,ith)=bpf(iph,ith)+bamp(m+1,m)*angpart(iph)*cp_mp1_m(ith)
443 c1=dsqrt((4.d0*ld**2-1.d0)/(ld**2-md**2))
444 c2=dsqrt((2.d0*ld+1.d0)*((ld-1.d0)**2-md**2)/(2.d0*ld-3.d0)/(ld**2-md**2))
445 cp_l_m=c1*miu*cp_lm1_m-c2*cp_lm2_m
446 angpart=dcos(md*phi+phase(
l,m))
449 bpf(iph,ith)=bpf(iph,ith)+bamp(
l,m)*angpart(iph)*cp_l_m(ith)
456 end subroutine inv_sph_transform
458 subroutine fft(a,b,ntot,n,nspan,isn)
502 double precision :: a(:),b(:)
506 dimension nfac(11),np(209)
508 dimension at(23),ck(23),bt(23),sk(23)
509 double precision :: c72,s72,s120,rad,radf,sd,cd,ak,bk,c1
510 double precision :: s1,aj,bj,akp,ajp,ajm,akm,bkp,bkm,bjp,bjm,aa
511 double precision :: bb,sk,ck,at,bt,s3,c3,s2,c2
512 integer :: i,ii,maxp,maxf,n,inc,isn,nt,ntot,ks,nspan,kspan,nn,jc,jf,m
513 integer :: k,j,jj,nfac,kt,np,kk,k1,k2,k3,k4,kspnn
527 c72=0.30901699437494742d0
528 s72=0.95105651629515357d0
529 s120=0.86602540378443865d0
530 rad=6.2831853071796d0
531 if(isn .ge. 0)
go to 10
541 radf=rad*dble(jc)*0.5d0
551 20
if(k-(k/16)*16 .eq. 0)
go to 15
558 30
if(mod(k,jj) .eq. 0)
go to 25
561 if(jj .le. k)
go to 30
562 if(k .gt. 4)
go to 40
567 40
if(k-(k/4)*4 .ne. 0)
go to 50
573 60
if(mod(k,j) .ne. 0)
go to 70
578 if(j .le. k)
go to 60
579 80
if(kt .eq. 0)
go to 100
584 if(j .ne. 0)
go to 90
586 100 sd=radf/dble(kspan)
591 if(nfac(i) .ne. 2)
go to 400
603 if(kk .le. nn)
go to 210
605 if(kk .le. jc)
go to 210
606 if(kk .gt. kspan)
go to 800
617 if(kk .lt. nt)
go to 230
621 if(kk .gt. k2)
go to 230
624 c1=2.d0-(ak**2+s1**2)
628 if(kk .lt. k2)
go to 230
631 if(kk .le. jc+jc)
go to 220
644 aj=(a(k1)-a(k2))*s120
645 bj=(b(k1)-b(k2))*s120
651 if(kk .lt. nn)
go to 320
653 if(kk .le. kspan)
go to 320
656 400
if(nfac(i) .ne. 4)
go to 600
676 if(isn .lt. 0)
go to 450
681 if(s1 .eq. 0.d0)
go to 460
682 430 a(k1)=akp*c1-bkp*s1
689 if(kk .le. nt)
go to 420
690 440 c2=c1-(cd*c1+sd*s1)
692 c1=2.d0-(c2**2+s1**2)
700 if(kk .le. kspan)
go to 420
702 if(kk .le. jc)
go to 410
703 if(kspan .eq. jc)
go to 800
709 if(s1 .ne. 0)
go to 430
717 if(kk .le. nt)
go to 420
755 if(kk .lt. nn)
go to 520
757 if(kk .le. kspan)
go to 520
763 if(k .eq. 3)
go to 320
764 if(k .eq. 5)
go to 510
765 if(k .eq. jf)
go to 640
770 if(jf .gt. maxf)
go to 998
774 630 ck(j)=ck(k)*c1+sk(k)*s1
775 sk(j)=ck(k)*s1-sk(k)*c1
780 if(j .lt. k)
go to 630
799 if(k1 .lt. k2)
go to 650
820 if(jj .gt. jf) jj=jj-jf
821 if(k .lt. jf)
go to 670
828 if(j .lt. k)
go to 660
830 if(kk .le. nn)
go to 640
832 if(kk .le. kspan)
go to 640
834 700
if(i .eq. m)
go to 800
845 if(kk .le. nt)
go to 730
850 if(kk .le. kspnn)
go to 730
853 c1=2.d0-(c2**2+s1**2)
857 if(kk .le. kspan)
go to 720
859 if(kk .le. jc+jc)
go to 710
864 if(kt .eq. 0)
go to 890
869 810 np(j+1)=np(j)/nfac(j)
870 np(k)=np(k+1)*nfac(j)
873 if(j .lt. k)
go to 810
879 if(n .ne. ntot)
go to 850
889 if(k2 .lt. ks)
go to 820
893 if(k2 .gt. np(j))
go to 830
895 840
if(kk .lt. k2)
go to 820
898 if(k2 .lt. ks)
go to 840
899 if(kk .lt. ks)
go to 830
912 if(kk .lt. k)
go to 860
915 if(kk .lt. nt)
go to 850
918 if(k2 .lt. ks)
go to 850
922 if(k2 .gt. np(j))
go to 870
924 880
if(kk .lt. k2)
go to 850
927 if(k2 .lt. ks)
go to 880
928 if(kk .lt. ks)
go to 870
930 890
if(2*kt+1 .ge. m)
return
935 900 nfac(j)=nfac(j)*nfac(j+1)
937 if(j .ne. kt)
go to 900
940 if(nn .gt. maxp)
go to 998
949 if(jj .ge. k2)
go to 902
955 if(j .le. nn)
go to 904
962 if(kk .ne. j)
go to 910
966 if(kk .lt. 0)
go to 914
967 if(kk .ne. j)
go to 910
969 if(j .ne. nn)
go to 914
974 if(np(j) .lt. 0)
go to 924
977 if(jj .gt. maxf) kspan=maxf
987 if(k1 .ne. kk)
go to 928
995 if(k1 .ne. kk)
go to 936
997 if(k .ne. j)
go to 932
1004 if(k1 .ne. kk)
go to 940
1005 if(jj .ne. 0)
go to 926
1006 if(j .ne. 1)
go to 924
1010 if(nt .ge. 0)
go to 924
1016 999
format(44h0array bounds exceeded within
subroutine fft)
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
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.
double precision, 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...
double precision, public r_0
subroutine, public pfss(ixil, ixol, bpf, x)
subroutine, public harm_coef(mapname)
double precision, public r_s