From c20d275cf681b0d25da32f59d4638e9218320cf2 Mon Sep 17 00:00:00 2001 From: Douglas Guptill <douglas.guptill@dal.ca> Date: Mon, 20 Jul 2009 01:16:12 +0000 Subject: [PATCH] try 2 specialized octree_interpolate_ subroutines --- OCTREE/Makefile | 2 + OCTREE/octree_interpolate_three.f90 | 116 +++++++++ .../octree_interpolate_three_derivative.f90 | 220 ++++++++++++++++++ move_surface.f90 | 7 +- 4 files changed, 343 insertions(+), 2 deletions(-) create mode 100644 OCTREE/octree_interpolate_three.f90 create mode 100644 OCTREE/octree_interpolate_three_derivative.f90 diff --git a/OCTREE/Makefile b/OCTREE/Makefile index 49aa4396..1fc13da2 100644 --- a/OCTREE/Makefile +++ b/OCTREE/Makefile @@ -9,6 +9,8 @@ graph_sloan.o \ isorti_sloan.o \ label_sloan.o \ number_sloan.o \ +octree_interpolate_three.o \ +octree_interpolate_three_derivative.o \ profil_sloan.o \ rootls_sloan.o diff --git a/OCTREE/octree_interpolate_three.f90 b/OCTREE/octree_interpolate_three.f90 new file mode 100644 index 00000000..b037413e --- /dev/null +++ b/OCTREE/octree_interpolate_three.f90 @@ -0,0 +1,116 @@ +subroutine octree_interpolate_three(nf,octree,noctree,icon,nleaves,nfield,x,y,z, & + field1,f1,field2,f2,field3,f3) + +! octree_interpolate_many specialized for 3 +! optional parameters removed. +! Author: Douglas Guptill +! Date: 2009-07-19 + +! This function returns the value of three fields (fieldi) known at the nodes +! of an octree by trilinear interpolation + +! nf is the number of fields being interpolate (must be 3) +! icon is the connectivity matrix +! nleaves is the number of leaves in the octree +! fieldi are the arrays of dimension nfield containing the fields +! known at the nodes of the octree and to be interpolated +! x,y,z are the location of the point where the fields are to be interpolated +! fi are the resulting interpolated fields + +implicit none + + +integer noctree,octree(noctree),nleaves,icon(8,nleaves) +integer nfield,nf +double precision field1(nfield),field2(nfield),field3(nfield) +double precision f1,f2,f3 +double precision x,y,z,x0,y0,z0,dxyz,r,s,t,h(8),phi,xt,yt,zt +integer leaf,level,loc,k,iii,jjj,kkk,ii + +! function modified by JEAN BRAUN on September 26 2005 +! to correct for an error in the logics that led to an interpolation +! from an octree to another identical octree with differences in the +! interpolated function. The reason for this problem was related to +! bad faces or hanging nodes. Indeed, for a hanging node it was very likely +! that the leaf that was detected as the loeaf in which the node resides +! was in fact a leave where the node was a hanging node (ie not one of the +! 4 corner nodes). This meant that the interpolated value was not equal +! to the "constrained" value imposed by the linear constraint at the +! hanging node. To correct for this we first check if the node can +! be interpolated with r,s,t values that are equal to 1 or -1. If this is +! true than this value is chosen as this would correspond to a nodal value + +xt=x +yt=y +zt=z + +if (xt.lt.-1.e-11 .or. xt.gt.1.d0+1.d-11) return +if (yt.lt.-1.e-11 .or. yt.gt.1.d0+1.d-11) return +if (zt.lt.-1.e-11 .or. zt.gt.1.d0+1.d-11) return + +if (x.lt.1.e-11) xt=1.e-11 +if (x.gt.1.d0-1.d-11) xt=1.d0-1.d-11 +if (y.lt.1.e-11) yt=1.e-11 +if (y.gt.1.d0-1.d-11) yt=1.d0-1.d-11 +if (z.lt.1.e-11) zt=1.e-11 +if (z.gt.1.d0-1.d-11) zt=1.d0-1.d-11 + +do kkk=-1,1,2 + do jjj=-1,1,2 + do iii=-1,1,2 + + xt=x+iii*1.d-10 + yt=y+jjj*1.d-10 + zt=z+kkk*1.d-10 + + if (xt*(xt-1.d0).ge.0d0 .or. & + yt*(yt-1.d0).ge.0d0 .or. & + zt*(zt-1.d0).ge.0d0) goto 111 + + call octree_find_leaf (octree,noctree,xt,yt,zt,leaf,level,loc,x0,y0,z0,dxyz) + + r=(x-x0)/dxyz*2.d0-1.d0 + s=(y-y0)/dxyz*2.d0-1.d0 + t=(z-z0)/dxyz*2.d0-1.d0 + h(1)=(1.d0-r)*(1.d0-s)*(1.d0-t)/8.d0 + h(2)=(1.d0+r)*(1.d0-s)*(1.d0-t)/8.d0 + h(3)=(1.d0-r)*(1.d0+s)*(1.d0-t)/8.d0 + h(4)=(1.d0+r)*(1.d0+s)*(1.d0-t)/8.d0 + h(5)=(1.d0-r)*(1.d0-s)*(1.d0+t)/8.d0 + h(6)=(1.d0+r)*(1.d0-s)*(1.d0+t)/8.d0 + h(7)=(1.d0-r)*(1.d0+s)*(1.d0+t)/8.d0 + h(8)=(1.d0+r)*(1.d0+s)*(1.d0+t)/8.d0 + phi=0.d0 + do k=1,8 + phi=phi+h(k)*field1(icon(k,leaf)) + enddo + f1=phi + if (nf.eq.1) goto 222 + phi=0.d0 + do k=1,8 + phi=phi+h(k)*field2(icon(k,leaf)) + enddo + f2=phi + if (nf.eq.2) goto 222 + phi=0.d0 + do k=1,8 + phi=phi+h(k)*field3(icon(k,leaf)) + enddo + f3=phi + if (nf.eq.3) goto 222 + +222 continue + !if (abs(r)-1.d0+abs(s)-1.d0+abs(t)-1.d0.lt.1.d-10) return + if (abs(abs(r)-1.d0).lt.1.d-10 .and. & + abs(abs(s)-1.d0).lt.1.d-10 .and. & + abs(abs(t)-1.d0).lt.1.d-10) return + +111 continue + + enddo + enddo +enddo + +return +end + diff --git a/OCTREE/octree_interpolate_three_derivative.f90 b/OCTREE/octree_interpolate_three_derivative.f90 new file mode 100644 index 00000000..5556ada7 --- /dev/null +++ b/OCTREE/octree_interpolate_three_derivative.f90 @@ -0,0 +1,220 @@ +subroutine octree_interpolate_three_derivative & + (nf,octree,noctree,icon,nleaves,nfield,x,y,z, & + field1,f1,df1x,df1y,df1z, & + field2,f2,df2x,df2y,df2z, & + field3,f3,df3x,df3y,df3z) + +! octree_interpolate_many_derivative specialized for 3 +! optional parameters removed. +! Author: Douglas Guptill +! Date: 2009-07-19 + +! This function returns the value of several fields (fieldi) known at the nodes +! of an octree by trilinear interpolation as well as their 3 spatial derivatives + +! nf is the number of fields being interpolate (must be 3) +! icon is the connectivity matrix +! nleaves is the number of leaves in the octree +! fieldi are the arrays of dimension nfield containing the fields +! known at the nodes of the octree and to be interpolated +! x,y,z are the location of the point where the fields are to be interpolated +! fi are the resulting interpolated fields + + +implicit none + +integer noctree,octree(noctree),nleaves,icon(8,nleaves) +integer nfield,nf +double precision field1(nfield),field2(nfield),field3(nfield) +double precision f1,f2,f3 +double precision df1x,df2x,df3x +double precision df1y,df2y,df3y +double precision df1z,df2z,df3z +double precision x,y,z,x0,y0,z0,dxyz,r,s,t,h(8),phi,xt,yt,zt +double precision phix,phiy,phiz +integer leaf,level,loc,k,iii,jjj,kkk,ii,jj,kk,ic,ijk +double precision dhdr(8),dhds(8),dhdt(8),xg(8),yg(8),zg(8),jcb(3,3),jcbi(3,3),volume +double precision dhdx(8),dhdy(8),dhdz(8) + +! function modified by JEAN BRAUN on September 26 2005 +! to correct for an error in the logics that led to an interpolation +! from an octree to another identical octree with differences in the +! interpolated function. The reason for this problem was related to +! bad faces or hanging nodes. Indeed, for a hanging node it was very likely +! that the leaf that was detected as the loeaf in which the node resides +! was in fact a leave where the node was a hanging node (ie not one of the +! 4 corner nodes). This meant that the interpolated value was not equal +! to the "constrained" value imposed by the linear constraint at the +! hanging node. To correct for this we first check if the node can +! be interpolated with r,s,t values that are equal to 1 or -1. If this is +! true than this value is chosen as this would correspond to a nodal value + +xt=x +yt=y +zt=z + +if (xt.lt.-1.e-11 .or. xt.gt.1.d0+1.d-11) return +if (yt.lt.-1.e-11 .or. yt.gt.1.d0+1.d-11) return +if (zt.lt.-1.e-11 .or. zt.gt.1.d0+1.d-11) return + +if (x.lt.1.e-11) xt=1.e-11 +if (x.gt.1.d0-1.d-11) xt=1.d0-1.d-11 +if (y.lt.1.e-11) yt=1.e-11 +if (y.gt.1.d0-1.d-11) yt=1.d0-1.d-11 +if (z.lt.1.e-11) zt=1.e-11 +if (z.gt.1.d0-1.d-11) zt=1.d0-1.d-11 + +do kkk=-1,1,2 +do jjj=-1,1,2 +do iii=-1,1,2 + +xt=x+iii*1.d-10 +yt=y+jjj*1.d-10 +zt=z+kkk*1.d-10 + +if (xt*(xt-1.d0).ge.0d0 .or. yt*(yt-1.d0).ge.0d0 .or. zt*(zt-1.d0).ge.0d0) goto 111 + +call octree_find_leaf (octree,noctree,xt,yt,zt,leaf,level,loc,x0,y0,z0,dxyz) + +r=(x-x0)/dxyz*2.d0-1.d0 +s=(y-y0)/dxyz*2.d0-1.d0 +t=(z-z0)/dxyz*2.d0-1.d0 +h(1)=(1.d0-r)*(1.d0-s)*(1.d0-t)/8.d0 +h(2)=(1.d0+r)*(1.d0-s)*(1.d0-t)/8.d0 +h(3)=(1.d0-r)*(1.d0+s)*(1.d0-t)/8.d0 +h(4)=(1.d0+r)*(1.d0+s)*(1.d0-t)/8.d0 +h(5)=(1.d0-r)*(1.d0-s)*(1.d0+t)/8.d0 +h(6)=(1.d0+r)*(1.d0-s)*(1.d0+t)/8.d0 +h(7)=(1.d0-r)*(1.d0+s)*(1.d0+t)/8.d0 +h(8)=(1.d0+r)*(1.d0+s)*(1.d0+t)/8.d0 +dhdr(1)=-(1.d0-s)*(1.d0-t)/8.d0 +dhdr(2)=(1.d0-s)*(1.d0-t)/8.d0 +dhdr(3)=-(1.d0+s)*(1.d0-t)/8.d0 +dhdr(4)=(1.d0+s)*(1.d0-t)/8.d0 +dhdr(5)=-(1.d0-s)*(1.d0+t)/8.d0 +dhdr(6)=(1.d0-s)*(1.d0+t)/8.d0 +dhdr(7)=-(1.d0+s)*(1.d0+t)/8.d0 +dhdr(8)=(1.d0+s)*(1.d0+t)/8.d0 +dhds(1)=-(1.d0-r)*(1.d0-t)/8.d0 +dhds(2)=-(1.d0+r)*(1.d0-t)/8.d0 +dhds(3)=(1.d0-r)*(1.d0-t)/8.d0 +dhds(4)=(1.d0+r)*(1.d0-t)/8.d0 +dhds(5)=-(1.d0-r)*(1.d0+t)/8.d0 +dhds(6)=-(1.d0+r)*(1.d0+t)/8.d0 +dhds(7)=(1.d0-r)*(1.d0+t)/8.d0 +dhds(8)=(1.d0+r)*(1.d0+t)/8.d0 +dhdt(1)=-(1.d0-r)*(1.d0-s)/8.d0 +dhdt(2)=-(1.d0+r)*(1.d0-s)/8.d0 +dhdt(3)=-(1.d0-r)*(1.d0+s)/8.d0 +dhdt(4)=-(1.d0+r)*(1.d0+s)/8.d0 +dhdt(5)=(1.d0-r)*(1.d0-s)/8.d0 +dhdt(6)=(1.d0+r)*(1.d0-s)/8.d0 +dhdt(7)=(1.d0-r)*(1.d0+s)/8.d0 +dhdt(8)=(1.d0+r)*(1.d0+s)/8.d0 +ijk=0 +do kk=0,1 +do jj=0,1 +do ii=0,1 +ijk=ijk+1 +xg(ijk)=x0+ii*dxyz +yg(ijk)=y0+jj*dxyz +zg(ijk)=z0+kk*dxyz +enddo +enddo +enddo +jcb=0. +do k=1,8 +jcb(1,1)=jcb(1,1)+dhdr(k)*xg(k) +jcb(1,2)=jcb(1,2)+dhdr(k)*yg(k) +jcb(1,3)=jcb(1,3)+dhdr(k)*zg(k) +jcb(2,1)=jcb(2,1)+dhds(k)*xg(k) +jcb(2,2)=jcb(2,2)+dhds(k)*yg(k) +jcb(2,3)=jcb(2,3)+dhds(k)*zg(k) +jcb(3,1)=jcb(3,1)+dhdt(k)*xg(k) +jcb(3,2)=jcb(3,2)+dhdt(k)*yg(k) +jcb(3,3)=jcb(3,3)+dhdt(k)*zg(k) +enddo + +volume=jcb(1,1)*jcb(2,2)*jcb(3,3)+jcb(1,2)*jcb(2,3)*jcb(3,1) & ++jcb(2,1)*jcb(3,2)*jcb(1,3) & +-jcb(1,3)*jcb(2,2)*jcb(3,1)-jcb(1,2)*jcb(2,1)*jcb(3,3) & +-jcb(2,3)*jcb(3,2)*jcb(1,1) + +jcbi(1,1)=(jcb(2,2)*jcb(3,3)-jcb(2,3)*jcb(3,2))/volume +jcbi(2,1)=(jcb(2,3)*jcb(3,1)-jcb(2,1)*jcb(3,3))/volume +jcbi(3,1)=(jcb(2,1)*jcb(3,2)-jcb(2,2)*jcb(3,1))/volume +jcbi(1,2)=(jcb(1,3)*jcb(3,2)-jcb(1,2)*jcb(3,3))/volume +jcbi(2,2)=(jcb(1,1)*jcb(3,3)-jcb(1,3)*jcb(3,1))/volume +jcbi(3,2)=(jcb(1,2)*jcb(3,1)-jcb(1,1)*jcb(3,2))/volume +jcbi(1,3)=(jcb(1,2)*jcb(2,3)-jcb(1,3)*jcb(2,2))/volume +jcbi(2,3)=(jcb(1,3)*jcb(2,1)-jcb(1,1)*jcb(2,3))/volume +jcbi(3,3)=(jcb(1,1)*jcb(2,2)-jcb(1,2)*jcb(2,1))/volume + +do k=1,8 +dhdx(k)=jcbi(1,1)*dhdr(k)+jcbi(1,2)*dhds(k)+jcbi(1,3)*dhdt(k) +dhdy(k)=jcbi(2,1)*dhdr(k)+jcbi(2,2)*dhds(k)+jcbi(2,3)*dhdt(k) +dhdz(k)=jcbi(3,1)*dhdr(k)+jcbi(3,2)*dhds(k)+jcbi(3,3)*dhdt(k) +enddo + + phi=0.d0 + phix=0.d0 + phiy=0.d0 + phiz=0.d0 + do k=1,8 + ic=icon(k,leaf) + phi=phi+h(k)*field1(ic) + phix=phix+dhdx(k)*field1(ic) + phiy=phiy+dhdy(k)*field1(ic) + phiz=phiz+dhdz(k)*field1(ic) + enddo + f1=phi + df1x=phix + df1y=phiy + df1z=phiz +if (nf.eq.1) goto 222 + phi=0.d0 + phix=0.d0 + phiy=0.d0 + phiz=0.d0 + do k=1,8 + ic=icon(k,leaf) + phi=phi+h(k)*field2(ic) + phix=phix+dhdx(k)*field2(ic) + phiy=phiy+dhdy(k)*field2(ic) + phiz=phiz+dhdz(k)*field2(ic) + enddo + f2=phi + df2x=phix + df2y=phiy + df2z=phiz +if (nf.eq.2) goto 222 + phi=0.d0 + phix=0.d0 + phiy=0.d0 + phiz=0.d0 + do k=1,8 + ic=icon(k,leaf) + phi=phi+h(k)*field3(ic) + phix=phix+dhdx(k)*field3(ic) + phiy=phiy+dhdy(k)*field3(ic) + phiz=phiz+dhdz(k)*field3(ic) + enddo + f3=phi + df3x=phix + df3y=phiy + df3z=phiz + + +222 continue +!if (abs(r)-1.d0+abs(s)-1.d0+abs(t)-1.d0.lt.1.d-10) return +if (abs(abs(r)-1.d0).lt.1.d-10 .and. abs(abs(s)-1.d0).lt.1.d-10 .and. abs(abs(t)-1.d0).lt.1.d-10) return + +111 continue + +enddo +enddo +enddo + +return +end + diff --git a/move_surface.f90 b/move_surface.f90 index 7e31fa14..5762339d 100644 --- a/move_surface.f90 +++ b/move_surface.f90 @@ -125,7 +125,7 @@ do i=iproc+1,surface%nsurface,nproc xi=(x0+x)/2.d0 yi=(y0+y)/2.d0 zi=(z0+z)/2.d0 - call octree_interpolate_many (3,ov%octree,ov%noctree,ov%icon,ov%nleaves, & + call octree_interpolate_three (3,ov%octree,ov%noctree,ov%icon,ov%nleaves, & ov%nnode,xi,yi,zi,ov%unode,u,ov%vnode,v,ov%wnode,w) if (i==1 .or. i==nside .or. i==2*nside-1 .or. i==3*nside-2) then !corner points @@ -152,7 +152,7 @@ do i=iproc+1,surface%nsurface,nproc ybuf(i)=y zbuf(i)=z if (params%normaladvect) then - call octree_interpolate_many_derivative (3,ov%octree,ov%noctree,ov%icon,ov%nleaves, & + call octree_interpolate_three_derivative (3,ov%octree,ov%noctree,ov%icon,ov%nleaves, & ov%nnode,xi,yi,zi, & ov%unode,u,ux,uy,uz, & ov%vnode,v,vx,vy,vz, & @@ -180,6 +180,9 @@ do i=iproc+1,surface%nsurface,nproc xnbuf(i)=xn0+(yn1*zln2-zn1*yln2+yln1*zn2-zln1*yn2)*dt+(yln1*zln2-zln1*yln2)*dt**2 ynbuf(i)=yn0+(zn1*xln2-xn1*zln2+zln1*xn2-xln1*zn2)*dt+(zln1*xln2-xln1*zln2)*dt**2 znbuf(i)=zn0+(xn1*yln2-yn1*xln2+xln1*yn2-yln1*xn2)*dt+(xln1*yln2-yln1*xln2)*dt**2 + if (xnbuf(i).gt.1.d50) write(*,*) 'on proc ', iproc, ', xnbuf is large: ', xnbuf(i) + if (ynbuf(i).gt.1.d50) write(*,*) 'on proc ', iproc, ', ynbuf is large: ', ynbuf(i) + if (znbuf(i).gt.1.d50) write(*,*) 'on proc ', iproc, ', znbuf is large: ', znbuf(i) xyzn=sqrt(xnbuf(i)**2+ynbuf(i)**2+znbuf(i)**2) xnbuf(i)=xnbuf(i)/xyzn ynbuf(i)=ynbuf(i)/xyzn -- GitLab