! volume from sidej
do k = 1,1
do j = 1,nf
do i = 1,nz
xmid = 0.5 * ( x(i,j,k) + x(i+1,j+1,k+1) )
ymid = 0.5 * ( y(i,j,k) + y(i+1,j+1,k+1) )
zmid = 0.5 * ( z(i,j,k) + z(i+1,j+1,k+1) )
ax1 = x(i,j,k) - xmid
ay1 = y(i,j,k) - ymid
az1 = z(i,j,k) - zmid
bx1 = x(i+1,j,k) - xmid
by1 = y(i+1,j,k) - ymid
bz1 = z(i+1,j,k) - zmid
cx1 = x(i,j,k+1) - xmid
cy1 = y(i,j,k+1) - ymid
cz1 = z(i,j,k+1) - zmid
dx1 = by1 * cz1 - bz1 * cy1
dy1 = -( bx1 * cz1 - bz1 * cx1 )
dz1 = bx1 * cy1 - by1 * cx1
v1 = 0.166667 *
. abs(( ax1 * dx1 + ay1 * dy1 + az1 * dz1 ))
ax2 = x(i+1,j,k+1) - xmid
ay2 = y(i+1,j,k+1) - ymid
az2 = z(i+1,j,k+1) - zmid
v2 = 0.166667 *
. abs(( ax2 * dx1 + ay2 * dy1 + az2 * dz1 ))
ax1 = x(i,j+1,k) - xmid
ay1 = y(i,j+1,k) - ymid
az1 = z(i,j+1,k) - zmid
bx1 = x(i+1,j+1,k) - xmid
by1 = y(i+1,j+1,k) - ymid
bz1 = z(i+1,j+1,k) - zmid
cx1 = x(i,j+1,k+1) - xmid
cy1 = y(i,j+1,k+1) - ymid
cz1 = z(i,j+1,k+1) - zmid
dx1 = by1 * cz1 - bz1 * cy1
dy1 = -( bx1 * cz1 - bz1 * cx1 )
dz1 = bx1 * cy1 - by1 * cx1
v3 = 0.166667 *
. abs(( ax1 * dx1 + ay1 * dy1 + az1 * dz1 ))
ax2 = x(i+1,j+1,k+1) - xmid
ay2 = y(i+1,j+1,k+1) - ymid
az2 = z(i+1,j+1,k+1) - zmid
v4 = 0.166667 *
. abs(( ax2 * dx1 + ay2 * dy1 + az2 * dz1 ))
volj(i,j) = v1 + v2 + v3 + v4
enddo
enddo
enddo
! volume from sidek
do k = 1,1
do j = 1,nf
do i = 1,nz
xmid = 0.5 * ( x(i,j,k) + x(i+1,j+1,k+1) )
ymid = 0.5 * ( y(i,j,k) + y(i+1,j+1,k+1) )
zmid = 0.5 * ( z(i,j,k) + z(i+1,j+1,k+1) )
ax1 = x(i,j,k) - xmid
ay1 = y(i,j,k) - ymid
az1 = z(i,j,k) - zmid
bx1 = x(i+1,j,k) - xmid
by1 = y(i+1,j,k) - ymid
bz1 = z(i+1,j,k) - zmid
cx1 = x(i,j+1,k) - xmid
cy1 = y(i,j+1,k) - ymid
cz1 = z(i,j+1,k) - zmid
dx1 = by1 * cz1 - bz1 * cy1
dy1 = -( bx1 * cz1 - bz1 * cx1 )
dz1 = bx1 * cy1 - by1 * cx1
v1 = 0.166667 *
. abs(( ax1 * dx1 + ay1 * dy1 + az1 * dz1 ))
ax2 = x(i+1,j+1,k) - xmid
ay2 = y(i+1,j+1,k) - ymid
az2 = z(i+1,j+1,k) - zmid
v2 = 0.166667 *
. abs(( ax2 * dx1 + ay2 * dy1 + az2 * dz1 ))
ax1 = x(i,j,k+1) - xmid
ay1 = y(i,j,k+1) - ymid
az1 = z(i,j,k+1) - zmid
bx1 = x(i+1,j,k+1) - xmid
by1 = y(i+1,j,k+1) - ymid
bz1 = z(i+1,j,k+1) - zmid
cx1 = x(i,j+1,k+1) - xmid
cy1 = y(i,j+1,k+1) - ymid
cz1 = z(i,j+1,k+1) - zmid
dx1 = by1 * cz1 - bz1 * cy1
dy1 = -( bx1 * cz1 - bz1 * cx1 )
dz1 = bx1 * cy1 - by1 * cx1
v3 = 0.166667 *
. abs(( ax1 * dx1 + ay1 * dy1 + az1 * dz1 ))
ax2 = x(i+1,j+1,k+1) - xmid
ay2 = y(i+1,j+1,k+1) - ymid
az2 = z(i+1,j+1,k+1) - zmid
v4 = 0.166667 *
. abs(( ax2 * dx1 + ay2 * dy1 + az2 * dz1 ))
volk(i,j) = v1 + v2 + v3 + v4
enddo
enddo
enddo
do j = 1,nf
do i = 1,nz
vol(i,j) = 1.e15 *
. ( voli(i,j) + volj(i,j) + volk(i,j) )
enddo
enddo
return
end
! *******************************************
! *******************************************
! area
! *******************************************
! *******************************************
subroutine area(x,y,z)
! calculate areas of cell sides
! break each quadrilateral side into
! two triangles and use the formula:
! A = (1/2)|a x b|
! where
! a: vector from A to B
! b: vector from A to C
include 'param-0.98.inc'
include 'com-0.98.inc'
real x(nzp1,nfp1,2),y(nzp1,nfp1,2),z(nzp1,nfp1,2)
! sidei (s-direction)
do k = 1,1
do j = 1,nf
do i = 1,nzp1
ax1 = x(i,j+1,k) - x(i,j,k)
ay1 = y(i,j+1,k) - y(i,j,k)
az1 = z(i,j+1,k) - z(i,j,k)
bx1 = x(i,j,k+1) - x(i,j,k)
by1 = y(i,j,k+1) - y(i,j,k)
bz1 = z(i,j,k+1) - z(i,j,k)
cx1 = ay1 * bz1 - az1 * by1
cy1 = -( ax1 * bz1 - az1 * bx1 )
cz1 = ax1 * by1 - ay1 * bx1
a1 = 0.5 * sqrt ( cx1*cx1 + cy1*cy1 + cz1*cz1 )
ax2 = x(i,j+1,k) - x(i,j+1,k+1)
ay2 = y(i,j+1,k) - y(i,j+1,k+1)
az2 = z(i,j+1,k) - z(i,j+1,k+1)
bx2 = x(i,j,k+1) - x(i,j+1,k+1)
by2 = y(i,j,k+1) - y(i,j+1,k+1)
bz2 = z(i,j,k+1) - z(i,j+1,k+1)
cx2 = ay2 * bz2 - az2 * by2
cy2 = -( ax2 * bz2 - az2 * bx2 )
cz2 = ax2 * by2 - ay2 * bx2
a2 = 0.5 * sqrt ( cx2*cx2 + cy2*cy2 + cz2*cz2 )
areas(i,j) = ( a1 + a2 ) * 1.e10
enddo
enddo
enddo
! sidej (p-direction)
do k = 1,1
do j = 1,nfp1
do i = 1,nz
ax1 = x(i+1,j,k) - x(i,j,k)
ay1 = y(i+1,j,k) - y(i,j,k)
az1 = z(i+1,j,k) - z(i,j,k)
bx1 = x(i,j,k+1) - x(i,j,k)
by1 = y(i,j,k+1) - y(i,j,k)
bz1 = z(i,j,k+1) - z(i,j,k)
cx1 = ay1 * bz1 - az1 * by1
cy1 = -( ax1 * bz1 - az1 * bx1 )
cz1 = ax1 * by1 - ay1 * bx1
a1 = 0.5 * sqrt ( cx1*cx1 + cy1*cy1 + cz1*cz1 )
ax2 = x(i+1,j,k) - x(i+1,j,k+1)
ay2 = y(i+1,j,k) - y(i+1,j,k+1)
az2 = z(i+1,j,k) - z(i+1,j,k+1)
bx2 = x(i,j,k+1) - x(i+1,j,k+1)
by2 = y(i,j,k+1) - y(i+1,j,k+1)
bz2 = z(i,j,k+1) - z(i+1,j,k+1)
cx2 = ay2 * bz2 - az2 * by2
cy2 = -( ax2 * bz2 - az2 * bx2 )
cz2 = ax2 * by2 - ay2 * bx2
a2 = 0.5 * sqrt ( cx2*cx2 + cy2*cy2 + cz2*cz2 )
areap(i,j) = ( a1 + a2 ) * 1.e10
enddo
enddo
enddo
return
end
! *******************************************
! *******************************************
! line
! *******************************************
! *******************************************
subroutine line(x,y,z)
! calculate length of cell sides
include 'param-0.98.inc'
include 'com-0.98.inc'
real x(nzp1,nfp1,2),y(nzp1,nfp1,2),z(nzp1,nfp1,2)
real xdelh(nzp1,nfp1)
! xdels (s-direction)
do k = 1,2
do j = 1,nfp1
do i = 1,nz
ax1 = x(i+1,j,k) - x(i,j,k)
ay1 = y(i+1,j,k) - y(i,j,k)
az1 = z(i+1,j,k) - z(i,j,k)
xdels(i,j,k) = sqrt ( ax1*ax1 + ay1*ay1 + az1*az1 )
. * 1.e5
enddo
enddo
enddo
! xdelp (p-direction)
do k = 1,2
do j = 1,nf
do i = 1,nzp1
ax1 = x(i,j+1,k) - x(i,j,k)
ay1 = y(i,j+1,k) - y(i,j,k)
az1 = z(i,j+1,k) - z(i,j,k)
xdelp(i,j,k) = sqrt ( ax1*ax1 + ay1*ay1 + az1*az1 )
. * 1.e5
enddo
enddo
enddo
! xdelh (phi-direction)
do j = 1,nfp1
do i = 1,nzp1
ax1 = x(i,j,2) - x(i,j,1)
ay1 = y(i,j,2) - y(i,j,1)
az1 = z(i,j,2) - z(i,j,1)
xdelh(i,j) = sqrt ( ax1*ax1 + ay1*ay1 + az1*az1 )
. * 1.e5
enddo
enddo
return
end
! *******************************************
! *******************************************
! normal
! *******************************************
! *******************************************
subroutine normal ( x,y,z )
! calculate unit normal direction to cell face
! normal: c = a x b / |a x b|
include 'param-0.98.inc'
include 'com-0.98.inc'
real x(nzp1,nfp1,2),y(nzp1,nfp1,2),z(nzp1,nfp1,2)
! norms (normal to cell face in s-direction)
do j = 1,nf
do i = 1,nzp1
ax1 = x(i,j+1,2) - x(i,j,1)
ay1 = y(i,j+1,2) - y(i,j,1)
az1 = z(i,j+1,2) - z(i,j,1)
bx1 = x(i,j,2) - x(i,j+1,1)
by1 = y(i,j,2) - y(i,j+1,1)
bz1 = z(i,j,2) - z(i,j+1,1)
cx1 = ay1 * bz1 - az1 * by1
cy1 = -(ax1 * bz1 - az1 * bx1)
cz1 = ax1 * by1 - ay1 * bx1
ca1 = sqrt( cx1*cx1 + cy1*cy1 + cz1*cz1 )
xnorms(i,j) = cx1/ca1
ynorms(i,j) = cy1/ca1
znorms(i,j) = cz1/ca1
enddo
enddo
! normp (normal to cell face in p-direction)
do j = 1,nfp1
do i = 1,nz
ax1 = x(i,j,2) - x(i+1,j,1)
ay1 = y(i,j,2) - y(i+1,j,1)
az1 = z(i,j,2) - z(i+1,j,1)
bx1 = x(i+1,j,2) - x(i,j,1)
by1 = y(i+1,j,2) - y(i,j,1)
bz1 = z(i+1,j,2) - z(i,j,1)
cx1 = ay1 * bz1 - az1 * by1
cy1 = -(ax1 * bz1 - az1 * bx1)
cz1 = ax1 * by1 - ay1 * bx1
ca1 = sqrt( cx1*cx1 + cy1*cy1 + cz1*cz1 )
xnormp(i,j) = cx1/ca1
ynormp(i,j) = cy1/ca1
znormp(i,j) = cz1/ca1
enddo
enddo
! norml (normal to cell face in phi-direction: longitude)
! do j = 1,nf
! do i = 1,nzp1
! ax1 = x(i+1,j+1,1) - x(i,j,1)
! ay1 = y(i+1,j+1,1) - y(i,j,1)
! az1 = z(i+1,j+1,1) - z(i,j,1)
! bx1 = x(i,j+1,1) - x(i+1,j,1)
! by1 = y(i,j+1,1) - y(i+1,j,1)
! bz1 = z(i,j+1,1) - z(i+1,j,1)
! cx1 = ay1 * bz1 - az1 * by1
! cy1 = -(ax1 * bz1 - az1 * bx1)
! cz1 = ax1 * by1 - ay1 * bx1
! ca1 = sqrt( cx1*cx1 + cy1*cy1 + cz1*cz1 )
! xnorml(i,j) = cx1/ca1
! ynorml(i,j) = cy1/ca1
! znorml(i,j) = cz1/ca1
! enddo
! enddo
return
end
! *******************************************
! *******************************************
! vnormal
!*******************************************
!*******************************************
subroutine vnormal ( qs,blon0,brs )
! calculate e x b velocity direction
! change p but keep q constant
include 'param-0.98.inc'
include 'com-0.98.inc'
real qs(nz,nf),qss(nzp1,nf),pss(nzp1,nf)
real brs1(nzp1,nf),blats1(nzp1,nf)
real brs2(nzp1,nf),blats2(nzp1,nf)
real xs1(nzp1,nf),ys1(nzp1,nf),zs1(nzp1,nf)
real xs2(nzp1,nf),ys2(nzp1,nf),zs2(nzp1,nf)
real brs(nz,nf)
! open (unit=12, file='xs1.dat')
! open (unit=13, file='ys1.dat')
! open (unit=15, file='xs2.dat')
! open (unit=16, file='ys2.dat')
delps = .001
do j = 1,nf
do i = 1,nz-1
qss(i+1,j) = 0.5 * ( qs(i,j) + qs(i+1,j) )
enddo
qss(1,j) = qs(1,j) + 0.5 * ( qs(1,j) - qs(2,j) )
qss(nzp1,j) = qs(nz,j) + 0.5 * ( qs(nz,j) - qs(nz-1,j) )
enddo
do j = 1,nf
do i = 1,nz
pss(i+1,j) = ps(i,j)
enddo
enddo
do j = 1,nf
pss(1,j) = pss(2,j)
enddo
do j = 1,nf
do i = 1,nz+1
! grid 1 (at pss(i,j))
qtmp = qss(i,j)
pvalue = pss(i,j)
r = re*qp_solve(qtmp,pvalue)
brs1(i,j) = r
br_norm = r / re
blats1(i,j) = asin ( qss(i,j) * br_norm ** 2 ) * rtod
xs1(i,j) = brs1(i,j) * cos( blats1(i,j)*po180 ) *
. sin( blon0 * po180 )
ys1(i,j) = brs1(i,j) * sin( blats1(i,j)*po180 )
zs1(i,j) = brs1(i,j) * cos( blats1(i,j) * po180 ) *
. cos( blon0 * po180 )
! grid 2 (at pss(i,j)+delps)
qtmp = qss(i,j)
pvalue = pss(i,j) + delps
r = re*qp_solve(qtmp,pvalue)
brs2(i,j) = r
br_norm = r / re
blats2(i,j) = asin ( qss(i,j) * br_norm ** 2 ) * rtod
! grid in cartesian coordinates
xs2(i,j) = brs2(i,j) * cos( blats2(i,j)*po180 ) *
. sin( blon0 * po180 )
ys2(i,j) = brs2(i,j) * sin( blats2(i,j)*po180 )
zs2(i,j) = brs2(i,j) * cos( blats2(i,j) * po180 ) *
. cos( blon0 * po180 )
enddo
enddo
! direction of e x b velocity
do j = 1,nf
do i = 1,nzp1
ax1 = xs2(i,j) - xs1(i,j)
ay1 = ys2(i,j) - ys1(i,j)
az1 = zs2(i,j) - zs1(i,j)
a1 = sqrt ( ax1*ax1 + ay1*ay1 + az1*az1 )
vnx(i,j) = ax1 / a1
vny(i,j) = ay1 / a1
vnz(i,j) = az1 / a1
enddo
enddo
do i = 1,nzp1
vnx(i,nfp1) = vnx(i,nf)
vny(i,nfp1) = vny(i,nf)
vnz(i,nfp1) = vnz(i,nf)
enddo
return
end
! ********************************************************
function qp_solve(q,p)
real qp_solve,q,p
real term1,term2
! MS: Functionally unnecessary, but kind of neat. To get r from
! (q,p) one needs to find the root of a fourth-order polynomial.
! The code did this with a standard root-finding method,
! but, of course, there is a closed-form solution. Since the
! polynomial has no second or third order terms, the answer
! isn't completely ugly, and the code below gives the exact
! result. Note the special case for q = 0, i.e. points on
! the magnetic equator.
! if (p .eq. 0.) then
! print *,'p = 0 in qp_solve'
! stop
! endif
! if (q .eq. 0.) then
! qp_solve = p
! else
! term1 = ( (sqrt(27.) + sqrt(27.+256.*q**2*p**4)) /
! . (16.*abs(q)*p**2) ) ** (1./3.)
! term2 = 2./(abs(q)*sqrt(3.)) * (term1 - 1./term1)
! qp_solve = 0.5*sqrt(term2)*(sqrt(2./(p*q**2*sqrt(term2**3)) -
! . 1.) - 1.)
! endif
! MS: The formula is actually my third attempt. The first had huge
! cancellation problems when q was small, the second had smaller
! problems when term0 was large. This should be well-behaved
! everywhere. Massive algebra was involved along the way.
term0 = 256./27.*q**2*p**4
term1 = ( 1. + sqrt(1. + term0) )**(2./3.)
term2 = term0**(1./3.)
term3 = 0.5 * ( (term1**2 + term1*term2 +
. term2**2)/term1 )**(3./2.)
qp_solve = p * (4.*term3) / (1.+term3) /
. ( 1.+sqrt(2.*term3-1.) )
end
! IGRF_SUB.F
! contributed by Paul Bernhardt (NRL)
subroutine igrf_sub(phi0)
include 'param-0.98.inc'
include 'com-0.98.inc'
phi = phi0 * pie / 180.
x0 = -353.8674146847993 -
. 80.0112901196596*Cos(phi) +
. 165.9453553374371*Cos(2*phi) +
. 96.90976911496519*Cos(3*phi) -
. 41.234237919645906*Cos(4*phi) -
. 5.647625148538237*Cos(5*phi) +
. 29.81898130515779*Cos(6*phi) +
. 27.310156089558348*Cos(7*phi) +
. 7.017930973481185*Cos(8*phi) -
. 7.511889133487608*Cos(9*phi) -
. 6.720946815524082*Cos(10*phi) -
. 0.5967604884638268*Cos(11*phi) +
. 3.9340250001598633*Cos(12*phi) +
. 3.232375199053169*Cos(13*phi) +
. 0.1418342157838855*Cos(14*phi) -
. 1.7399223106946722*Cos(15*phi) -
. 1.2396197007828484*Cos(16*phi) +
. 0.24319862206273882*Cos(17*phi) +
. 1.0043588925588962*Cos(18*phi) +
. 0.6050359806604826*Cos(19*phi) -
. 0.2175679881607454*Cos(20*phi) -
. 0.5970638247030868*Cos(21*phi) -
. 0.3095886741276035*Cos(22*phi) +
. 0.24106351981877516*Cos(23*phi) -
. 39.488705071918595*Sin(phi) -
. 35.12750391544765*Sin(2*phi) -
. 52.61217403191678*Sin(3*phi) +
. 35.372208218215505*Sin(4*phi) +
. 62.517949955768565*Sin(5*phi) +
. 33.70515829546757*Sin(6*phi) -
. 6.367067330825964*Sin(7*phi) -
. 16.84168815021257*Sin(8*phi) -
. 8.77073458124951*Sin(9*phi) +
. 2.4509417362535326*Sin(10*phi) +
. 5.964643505586716*Sin(11*phi) +
. 2.7430884455100206*Sin(12*phi) -
. 1.469044512466587*Sin(13*phi) -
. 2.58647152886297*Sin(14*phi) -
. 0.9057773601920639*Sin(15*phi) +
. 0.9500051070510113*Sin(16*phi) +
. 1.2595308671288294*Sin(17*phi) +
. 0.30670958561561906*Sin(18*phi) -
. 0.6041955011153372*Sin(19*phi) -
. 0.669980882605414*Sin(20*phi) -
. 0.08600912796198656*Sin(21*phi) +
. 0.4475307568863845*Sin(22*phi) +
. 0.4538479001719651*Sin(23*phi)
y0 = 357.71572803711445 +
. 179.10000315892776*Cos(phi) +
. 0.48625012094252057*Cos(2*phi) -
. 18.222451520290683*Cos(3*phi) -
. 74.19071886155683*Cos(4*phi) -
. 36.523066435387676*Cos(5*phi) -
. 1.3391741086911595*Cos(6*phi) +
. 21.128815605008093*Cos(7*phi) +
. 12.30309152643703*Cos(8*phi) +
. 0.7072007210810681*Cos(9*phi) -
. 4.253716697410791*Cos(10*phi) -
. 1.9043150223068182*Cos(11*phi) +
. 1.5369582665526593*Cos(12*phi) +
. 2.322273352128386*Cos(13*phi) +
. 0.8660859526717453*Cos(14*phi) -
. 0.6517850740970705*Cos(15*phi) -
. 0.8233191201701169*Cos(16*phi) -
. 0.06587490166894897*Cos(17*phi) +
. 0.5590511561227545*Cos(18*phi) +
. 0.4857427492770479*Cos(19*phi) +
. 0.003220351289183923*Cos(20*phi) -
. 0.31210096865413983*Cos(21*phi) -
. 0.19887427994494658*Cos(22*phi) +
. 0.13672910587356485*Cos(23*phi) +
. 416.65605532707093*Sin(phi) +
. 97.64092937463448*Sin(2*phi) +
. 89.90576641057676*Sin(3*phi) +
. 19.563789031651595*Sin(4*phi) +
. 46.61385007838707*Sin(5*phi) +
. 46.23624804545088*Sin(6*phi) +
. 19.328984217463248*Sin(7*phi) +
. 2.4598324280936414*Sin(8*phi) -
. 3.4043388007500432*Sin(9*phi) +
. 2.111663037458501*Sin(10*phi) +
. 4.723429973505645*Sin(11*phi) +
. 3.7939791153184026*Sin(12*phi) +
. 0.783837405015646*Sin(13*phi) -
. 0.8951808216876126*Sin(14*phi) -
. 0.5853291438883146*Sin(15*phi) +
. 0.49374732010654354*Sin(16*phi) +
. 0.9299824387332063*Sin(17*phi) +
. 0.48650275322307124*Sin(18*phi) -
. 0.15694935678709498*Sin(19*phi) -
. 0.36063573138052973*Sin(20*phi) -
. 0.08389592287106021*Sin(21*phi) +
. 0.25573941044924925*Sin(22*phi) +
. 0.2852013162673946*Sin(23*phi) |