************************************************************************* * * Subroutine inter_B.f * * it computes the magnetic field in a chosen point x,y,z inside or * outside the magnetic cavity, using a trilinear interpolation of * B field measurements (read before by means of ./read_B.f) * if the point falls outside the interpolation volume, set the field to 0 * * needs: * - common_B_inner.f common file for the inner magnetic field map * - ./inter_B_inner.f common file for the inner magnetic field map * - common_B_outer.f common file for the outer magnetic field map * - ./inter_B_outer.f common file for the outer magnetic field map * * to be called after ./read_B.f (magnetic field map reading subroutine) * * input: coordinates in m * output: magnetic field in T * ************************************************************************* subroutine inter_B(x,y,z,res) !coordinates in m, magnetic field in T implicit double precision (a-h,o-z) include 'common_B.f' c------------------------------------------------------------------------ c c local variables c c------------------------------------------------------------------------ real*8 x,y,z !point of interest real*8 res(3) !interpolated B components: res = (Bx, By, Bz) real*8 zl,zu real*8 resu(3),resl(3) c------------------------------------------------------------------------ c c set the field outside the interpolation volume to be 0 c c------------------------------------------------------------------------ do ip=1,3 res(ip)=0. enddo c------------------------------------------------------------------------ c c check if the point falls inside the interpolation volumes c c------------------------------------------------------------------------ * ----------------------- * INNER MAP * ----------------------- if( $ (x.ge.edgexmin).and.(x.le.edgexmax) $ .and.(y.ge.edgeymin).and.(y.le.edgeymax) $ .and.(z.ge.edgezmin).and.(z.le.edgezmax) $ ) then call inter_B_inner(x,y,z,res) c print*,'INNER - ',z,res endif * ----------------------- * OUTER MAP * ----------------------- if( $ ((x.ge.edgeuxmin).and.(x.le.edgeuxmax) $ .and.(y.ge.edgeuymin).and.(y.le.edgeuymax) $ .and.(z.ge.edgeuzmin).and.(z.le.edgeuzmax)) $ .or. $ ((x.ge.edgelxmin).and.(x.le.edgelxmax) $ .and.(y.ge.edgelymin).and.(y.le.edgelymax) $ .and.(z.ge.edgelzmin).and.(z.le.edgelzmax)) $ ) then call inter_B_outer(x,y,z,res) c res(2)=res(2)*10 c print*,'OUTER - ',z,res endif * -------------------------------- * GAP between INNER and OUTER MAPS * -------------------------------- if( $ (x.gt.edgexmin).and.(x.lt.edgexmax) $ .and.(y.gt.edgeymin).and.(y.lt.edgeymax) $ .and.(z.gt.edgezmax).and.(z.lt.edgeuzmin) $ )then zu = edgeuzmin zl = edgezmax call inter_B_inner(x,y,zl,resu) call inter_B_outer(x,y,zu,resl) do i=1,3 res(i) = z * ((resu(i)-resl(i))/(zu-zl)) $ + resu(i) $ - zu * ((resu(i)-resl(i))/(zu-zl)) enddo c print*,'GAP U - ',z,res elseif( $ (x.gt.edgexmin).and.(x.lt.edgexmax) $ .and.(y.gt.edgeymin).and.(y.lt.edgeymax) $ .and.(z.gt.edgelzmax).and.(z.lt.edgezmin) $ ) then zu = edgezmin zl = edgelzmax call inter_B_inner(x,y,zu,resu) call inter_B_outer(x,y,zl,resl) do i=1,3 res(i) = z * ((resu(i)-resl(i))/(zu-zl)) $ + resu(i) $ - zu * ((resu(i)-resl(i))/(zu-zl)) enddo c print*,'GAP D - ',z,res endif return end ************************************************************************* * * Subroutine inter_B_inner.f * * it computes the magnetic field in a chosen point x,y,z inside the * magnetic cavity, using a trilinear interpolation of * B field measurements (read before by means of ./read_B.f) * the value is computed for two different inner maps and then averaged * * needs: * - ../common/common_B_inner.f * * input: coordinates in m * output: magnetic field in T * ************************************************************************* subroutine inter_B_inner(x,y,z,res) !coordinates in m, magnetic field in T implicit double precision (a-h,o-z) include 'common_B.f' c------------------------------------------------------------------------ c c local variables c c------------------------------------------------------------------------ real*8 x,y,z !point of interpolation real*8 res(3) !interpolated B components: res = (Bx, By, Bz) real*8 res1(3),res2(3) !interpolated B components for the two maps integer ic !index for B components: ! ic=1 ---> Bx ! ic=2 ---> By ! ic=3 ---> Bz integer cube(3) !vector of indexes identifying the cube ! containing the point of interpolation ! (see later...) real*8 xl,xh,yl,yh,zl,zh !cube vertexes coordinates real*8 xr,yr,zr !reduced variables (coordinates of the ! point of interpolation inside the cube) real*8 Bp(8) !vector of values of B component ! being computed, on the eight cube vertexes c------------------------------------------------------------------------ c c *** FIRST MAP *** c c------------------------------------------------------------------------ do ic=1,3 !loops on the three B components c------------------------------------------------------------------------ c c chooses the coordinates interval containing the input point c c------------------------------------------------------------------------ c e.g.: c c x1 x2 x3 x4 x5... c |-----|-+---|-----|-----|---- c ~~~~~~~~x c c in this case the right interval is identified by indexes 2-3, so the c value assigned to cube variable is 2 cube(1)=INT((nx-1)*(x-px1min(ic))/(px1max(ic)-px1min(ic))) +1 cube(2)=INT((ny-1)*(y-py1min(ic))/(py1max(ic)-py1min(ic))) +1 cube(3)=INT((nz-1)*(z-pz1min(ic))/(pz1max(ic)-pz1min(ic))) +1 c------------------------------------------------------------------------ c c if the point falls beyond the extremes of the grid... c c------------------------------------------------------------------------ c c ~~~~~~~~~~x1 x2 x3... c - - + - - |-----|-----|---- c ~~~~x c c in the case cube = 1 c c c ...nx-2 nx-1 nx c ----|-----|-----| - - - + - - c ~~~~~~~~~~~~~~~~~~~~~~~~x c c in this case cube = nx-1 if (cube(1).le.0) cube(1) = 1 if (cube(2).le.0) cube(2) = 1 if (cube(3).le.0) cube(3) = 1 if (cube(1).ge.nx) cube(1) = nx-1 if (cube(2).ge.ny) cube(2) = ny-1 if (cube(3).ge.nz) cube(3) = nz-1 c------------------------------------------------------------------------ c c temporary variables definition for field computation c c------------------------------------------------------------------------ xl = px1(cube(1),ic) !X coordinates of cube vertexes xh = px1(cube(1)+1,ic) yl = py1(cube(2),ic) !Y coordinates of cube vertexes yh = py1(cube(2)+1,ic) zl = pz1(cube(3),ic) !Z coordinates of cube vertexes zh = pz1(cube(3)+1,ic) xr = (x-xl) / (xh-xl) !reduced variables yr = (y-yl) / (yh-yl) zr = (z-zl) / (zh-zl) Bp(1) = b1(cube(1) ,cube(2) ,cube(3) ,ic) !ic-th component of B Bp(2) = b1(cube(1)+1,cube(2) ,cube(3) ,ic) ! on the eight cube Bp(3) = b1(cube(1) ,cube(2)+1,cube(3) ,ic) ! vertexes Bp(4) = b1(cube(1)+1,cube(2)+1,cube(3) ,ic) Bp(5) = b1(cube(1) ,cube(2) ,cube(3)+1,ic) Bp(6) = b1(cube(1)+1,cube(2) ,cube(3)+1,ic) Bp(7) = b1(cube(1) ,cube(2)+1,cube(3)+1,ic) Bp(8) = b1(cube(1)+1,cube(2)+1,cube(3)+1,ic) c------------------------------------------------------------------------ c c computes interpolated ic-th component of B in (x,y,z) c c------------------------------------------------------------------------ res1(ic) = + Bp(1)*(1-xr)*(1-yr)*(1-zr) + + Bp(2)*xr*(1-yr)*(1-zr) + + Bp(3)*(1-xr)*yr*(1-zr) + + Bp(4)*xr*yr*(1-zr) + + Bp(5)*(1-xr)*(1-yr)*zr + + Bp(6)*xr*(1-yr)*zr + + Bp(7)*(1-xr)*yr*zr + + Bp(8)*xr*yr*zr enddo c------------------------------------------------------------------------ c c *** SECOND MAP *** c c------------------------------------------------------------------------ c second map is rotated by 180 degree along the Z axis. so change sign c of x and y coordinates and then change sign to Bx and By components c to obtain the correct result x=-x y=-y do ic=1,3 cube(1)=INT((nx-1)*(x-px2min(ic))/(px2max(ic)-px2min(ic))) +1 cube(2)=INT((ny-1)*(y-py2min(ic))/(py2max(ic)-py2min(ic))) +1 cube(3)=INT((nz-1)*(z-pz2min(ic))/(pz2max(ic)-pz2min(ic))) +1 if (cube(1).le.0) cube(1) = 1 if (cube(2).le.0) cube(2) = 1 if (cube(3).le.0) cube(3) = 1 if (cube(1).ge.nx) cube(1) = nx-1 if (cube(2).ge.ny) cube(2) = ny-1 if (cube(3).ge.nz) cube(3) = nz-1 xl = px2(cube(1),ic) xh = px2(cube(1)+1,ic) yl = py2(cube(2),ic) yh = py2(cube(2)+1,ic) zl = pz2(cube(3),ic) zh = pz2(cube(3)+1,ic) xr = (x-xl) / (xh-xl) yr = (y-yl) / (yh-yl) zr = (z-zl) / (zh-zl) Bp(1) = b2(cube(1) ,cube(2) ,cube(3) ,ic) Bp(2) = b2(cube(1)+1,cube(2) ,cube(3) ,ic) Bp(3) = b2(cube(1) ,cube(2)+1,cube(3) ,ic) Bp(4) = b2(cube(1)+1,cube(2)+1,cube(3) ,ic) Bp(5) = b2(cube(1) ,cube(2) ,cube(3)+1,ic) Bp(6) = b2(cube(1)+1,cube(2) ,cube(3)+1,ic) Bp(7) = b2(cube(1) ,cube(2)+1,cube(3)+1,ic) Bp(8) = b2(cube(1)+1,cube(2)+1,cube(3)+1,ic) res2(ic) = + Bp(1)*(1-xr)*(1-yr)*(1-zr) + + Bp(2)*xr*(1-yr)*(1-zr) + + Bp(3)*(1-xr)*yr*(1-zr) + + Bp(4)*xr*yr*(1-zr) + + Bp(5)*(1-xr)*(1-yr)*zr + + Bp(6)*xr*(1-yr)*zr + + Bp(7)*(1-xr)*yr*zr + + Bp(8)*xr*yr*zr enddo c change Bx and By components sign res2(1)=-res2(1) res2(2)=-res2(2) c change back the x and y coordinate signs x=-x y=-y c------------------------------------------------------------------------ c c average the two maps results c c------------------------------------------------------------------------ do ic=1,3 res(ic)=(res1(ic)+res2(ic))/2 enddo return end ************************************************************************* * * Subroutine inter_B_outer.f * * it computes the magnetic field in a chosen point x,y,z OUTSIDE the * magnetic cavity, using a trilinear interpolation of * B field measurements (read before by means of ./read_B.f) * the value is computed for the outer map * * needs: * - ../common/common_B_outer.f * * input: coordinates in m * output: magnetic field in T * ************************************************************************* subroutine inter_B_outer(x,y,z,res) !coordinates in m, magnetic field in T implicit double precision (a-h,o-z) include 'common_B.f' c------------------------------------------------------------------------ c c local variables c c------------------------------------------------------------------------ real*8 x,y,z !point of interpolation real*8 res(3) !interpolated B components: res = (Bx, By, Bz) real*8 zin integer ic c !index for B components: c ! ic=1 ---> Bx c ! ic=2 ---> By c ! ic=3 ---> Bz integer cube(3) c !vector of indexes identifying the cube c ! containing the point of interpolation c ! (see later...) real*8 xl,xh,yl,yh,zl,zh !cube vertexes coordinates real*8 xr,yr,zr c !reduced variables (coordinates of the c ! point of interpolation inside the cube) real*8 Bp(8) c !vector of values of B component c ! being computed, on the eight cube vertexes c LOWER MAP c ---> up/down simmetry zin=z if(zin.le.edgelzmax)z=-z c------------------------------------------------------------------------ c c *** MAP *** c c------------------------------------------------------------------------ do ic=1,3 !loops on the three B components c------------------------------------------------------------------------ c c chooses the coordinates interval containing the input point c c------------------------------------------------------------------------ c e.g.: c c x1 x2 x3 x4 x5... xN c |-----|-+---|-----|-----|---- ... ----|-----| c ~~~~~~~~x c c in this case the right interval is identified by indexes 2-3, so the c value assigned to cube variable is 2 cube(1)=INT((nox-1)*(x-poxmin(ic))/(poxmax(ic)-poxmin(ic))) +1 cube(2)=INT((noy-1)*(y-poymin(ic))/(poymax(ic)-poymin(ic))) +1 cube(3)=INT((noz-1)*(z-pozmin(ic))/(pozmax(ic)-pozmin(ic))) +1 c------------------------------------------------------------------------ c c if the point falls beyond the extremes of the grid... c c------------------------------------------------------------------------ c c ~~~~~~~~~~x1 x2 x3... c - - + - - |-----|-----|---- c ~~~~x c c in the case cube = 1 c c c ...nx-2 nx-1 nx c ----|-----|-----| - - - + - - c ~~~~~~~~~~~~~~~~~~~~~~~~x c c in this case cube = nx-1 if (cube(1).le.0) cube(1) = 1 if (cube(2).le.0) cube(2) = 1 if (cube(3).le.0) cube(3) = 1 if (cube(1).ge.nox) cube(1) = nox-1 if (cube(2).ge.noy) cube(2) = noy-1 if (cube(3).ge.noz) cube(3) = noz-1 c------------------------------------------------------------------------ c c temporary variables definition for field computation c c------------------------------------------------------------------------ xl = pox(cube(1),ic) !X coordinates of cube vertexes xh = pox(cube(1)+1,ic) yl = poy(cube(2),ic) !Y coordinates of cube vertexes yh = poy(cube(2)+1,ic) zl = poz(cube(3),ic) !Z coordinates of cube vertexes zh = poz(cube(3)+1,ic) xr = (x-xl) / (xh-xl) !reduced variables yr = (y-yl) / (yh-yl) zr = (z-zl) / (zh-zl) Bp(1) = bo(cube(1) ,cube(2) ,cube(3) ,ic) !ic-th component of B Bp(2) = bo(cube(1)+1,cube(2) ,cube(3) ,ic) ! on the eight cube Bp(3) = bo(cube(1) ,cube(2)+1,cube(3) ,ic) ! vertexes Bp(4) = bo(cube(1)+1,cube(2)+1,cube(3) ,ic) Bp(5) = bo(cube(1) ,cube(2) ,cube(3)+1,ic) Bp(6) = bo(cube(1)+1,cube(2) ,cube(3)+1,ic) Bp(7) = bo(cube(1) ,cube(2)+1,cube(3)+1,ic) Bp(8) = bo(cube(1)+1,cube(2)+1,cube(3)+1,ic) c------------------------------------------------------------------------ c c computes interpolated ic-th component of B in (x,y,z) c c------------------------------------------------------------------------ res(ic) = + Bp(1)*(1-xr)*(1-yr)*(1-zr) + + Bp(2)*xr*(1-yr)*(1-zr) + + Bp(3)*(1-xr)*yr*(1-zr) + + Bp(4)*xr*yr*(1-zr) + + Bp(5)*(1-xr)*(1-yr)*zr + + Bp(6)*xr*(1-yr)*zr + + Bp(7)*(1-xr)*yr*zr + + Bp(8)*xr*yr*zr enddo c LOWER MAP c ---> up/down simmetry if(zin.le.edgelzmax)then z=-z !back to initial ccoordinate res(3)=-res(3) !invert BZ component endif return end