1*10167291SKenneth E. Jansen module wallData !was suctionDuct 2*10167291SKenneth E. Jansen logical wnormCalced 3*10167291SKenneth E. Jansen !integer nsuctionface 4*10167291SKenneth E. Jansen !integer, allocatable :: suctionf(:) 5*10167291SKenneth E. Jansen 6*10167291SKenneth E. Jansen !Threshold for determining whether a node is on a corner 7*10167291SKenneth E. Jansen real*8 :: cornerCosThresh 8*10167291SKenneth E. Jansen 9*10167291SKenneth E. Jansen !Wall normal array of size (nshg, 3) 10*10167291SKenneth E. Jansen real*8, allocatable :: wnorm(:,:) 11*10167291SKenneth E. Jansen contains 12*10167291SKenneth E. Jansen 13*10167291SKenneth E. Jansen subroutine findWallNorm(x,iBC,ilwork,iper) 14*10167291SKenneth E. Jansen 15*10167291SKenneth E. Jansen! use wallData 16*10167291SKenneth E. Jansen use pointer_data 17*10167291SKenneth E. Jansen include "common.h" 18*10167291SKenneth E. Jansen include "mpif.h" 19*10167291SKenneth E. Jansen 20*10167291SKenneth E. Jansen integer iBC(nshg) 21*10167291SKenneth E. Jansen real*8 x(numnp,nsd) 22*10167291SKenneth E. Jansen integer iper(nshg) 23*10167291SKenneth E. Jansen integer ilwork(nlwork) 24*10167291SKenneth E. Jansen integer, allocatable :: ienb(:) 25*10167291SKenneth E. Jansen real*8, allocatable :: wNormTmp(:,:) 26*10167291SKenneth E. Jansen real*8 eNorm(nsd),en(nsd),wn(nsd),aedg(nsd),bedg(nsd) 27*10167291SKenneth E. Jansen real*8 mag 28*10167291SKenneth E. Jansen! integer isfID 29*10167291SKenneth E. Jansen 30*10167291SKenneth E. Jansen real*8 wallBCout(nshg, 6) 31*10167291SKenneth E. Jansen real*8 BC(nshg,ndofBC) 32*10167291SKenneth E. Jansen 33*10167291SKenneth E. Jansen cornerCosThresh = 0.75d00 34*10167291SKenneth E. Jansen !The number 0.75 is somewhat arbitrary. The thinking is that this 35*10167291SKenneth E. Jansen !code is also used for the normal on curved surfaces which will have 36*10167291SKenneth E. Jansen !a non unit dot product from elements surrounding a wall vertex but 37*10167291SKenneth E. Jansen !acos(0.75) is a pretty big angle. On coarse meshes this number may 38*10167291SKenneth E. Jansen !have to be dialed down to get normal on curved walls correct. 39*10167291SKenneth E. Jansen 40*10167291SKenneth E. Jansen allocate(wNorm(nshg,nsd)) 41*10167291SKenneth E. Jansen wNorm = 0 42*10167291SKenneth E. Jansen 43*10167291SKenneth E. Jansen do iblk=1,nelblb !loop over all the bounday element blocks at current process 44*10167291SKenneth E. Jansen npro=lcblkb(1,iblk+1)-lcblkb(1,iblk) 45*10167291SKenneth E. Jansen nenbl=lcblkb(6,iblk) 46*10167291SKenneth E. Jansen nshl=lcblkb(9,iblk) 47*10167291SKenneth E. Jansen allocate(ienb(nshl)) 48*10167291SKenneth E. Jansen do i=1,npro ! loop over boundary elements 49*10167291SKenneth E. Jansen! isfID=miBCB(iblk)%p(i,2) ! miBCB(2) is the surfID 50*10167291SKenneth E. Jansen ienb(1:nshl)=mienb(iblk)%p(i,1:nshl) 51*10167291SKenneth E. Jansen do j=1,nenbl ! loop over boundary nodes 52*10167291SKenneth E. Jansen nn=ienb(j) !nn is the global index of suction node 53*10167291SKenneth E. Jansen if(j.ne.1.and.j.ne.nenbl)then 54*10167291SKenneth E. Jansen aedg(:)=x(ienb(j+1),:)-x(nn,:) 55*10167291SKenneth E. Jansen bedg(:)=x(ienb(j-1),:)-x(nn,:) 56*10167291SKenneth E. Jansen elseif(j.eq.1)then 57*10167291SKenneth E. Jansen aedg(:)=x(ienb(j+1),:)-x(nn,:) 58*10167291SKenneth E. Jansen bedg(:)=x(ienb(nenbl),:)-x(nn,:) 59*10167291SKenneth E. Jansen elseif(j.eq.nenbl)then 60*10167291SKenneth E. Jansen aedg(:)=x(ienb(1),:)-x(nn,:) 61*10167291SKenneth E. Jansen bedg(:)=x(ienb(j-1),:)-x(nn,:) 62*10167291SKenneth E. Jansen endif 63*10167291SKenneth E. Jansen eNorm(1)=aedg(2)*bedg(3)-aedg(3)*bedg(2) 64*10167291SKenneth E. Jansen eNorm(2)=aedg(3)*bedg(1)-aedg(1)*bedg(3) 65*10167291SKenneth E. Jansen eNorm(3)=aedg(1)*bedg(2)-aedg(2)*bedg(1) 66*10167291SKenneth E. Jansen 67*10167291SKenneth E. Jansen call addElemNormal(wNorm, eNorm, nn) 68*10167291SKenneth E. Jansen 69*10167291SKenneth E. Jansen enddo !end do j = 1, nenbl 70*10167291SKenneth E. Jansen enddo !end do i = 1, npro 71*10167291SKenneth E. Jansen deallocate(ienb) 72*10167291SKenneth E. Jansen enddo !end do iblk = 1, nelblk 73*10167291SKenneth E. Jansen 74*10167291SKenneth E. Jansen !Now communicate between parts. Note: there still may be a 75*10167291SKenneth E. Jansen !conflict if the boundary edge is on a corner, so a separate array 76*10167291SKenneth E. Jansen !needs to be used to allow us to repeat the z-norm comparison. 77*10167291SKenneth E. Jansen if(numpe.gt.1) then 78*10167291SKenneth E. Jansen allocate(wNormTmp(nshg,nsd)) 79*10167291SKenneth E. Jansen wNormTmp = wNorm 80*10167291SKenneth E. Jansen call commu(wNormTmp(:,:), ilwork, 3, 'in ') 81*10167291SKenneth E. Jansen wNormTmp = wNormTmp - wNorm !undo the addition in commu to just 82*10167291SKenneth E. Jansen !get contributions from other processors 83*10167291SKenneth E. Jansen 84*10167291SKenneth E. Jansen do i = 1,nshg !loop over each node and add the off 85*10167291SKenneth E. Jansen wn(:) = wNormTmp(i,:) !processor contribution. If this is 86*10167291SKenneth E. Jansen call addElemNormal(wNorm, wn, i) !an interior node, zero gets 87*10167291SKenneth E. Jansen enddo !added to zero. 88*10167291SKenneth E. Jansen endif 89*10167291SKenneth E. Jansen 90*10167291SKenneth E. Jansen !It is unclear how to treat periodic boundary conditions, i.e. 91*10167291SKenneth E. Jansen !should periodic walls have zero norm, a correct normal for each 92*10167291SKenneth E. Jansen !side, or a correct normal for the master. With bc3per commented, 93*10167291SKenneth E. Jansen !the wall normal should be calculated as though there is no 94*10167291SKenneth E. Jansen !periodic BC. 95*10167291SKenneth E. Jansen! call bc3per(iBC,wNorm(:,:),iper,ilwork,3) 96*10167291SKenneth E. Jansen 97*10167291SKenneth E. Jansen if(numpe.gt.1) call commu(wNorm(:,:),ilwork,3,'out') 98*10167291SKenneth E. Jansen 99*10167291SKenneth E. Jansen do nn = 1,nshg 100*10167291SKenneth E. Jansen wn(:) = wNorm(nn,:) 101*10167291SKenneth E. Jansen mag = (wn(1)**2+wn(2)**2+wn(3)**2)**0.5 102*10167291SKenneth E. Jansen 103*10167291SKenneth E. Jansen if(mag > 0) wNorm(nn,:) = wn(:)/mag 104*10167291SKenneth E. Jansen enddo 105*10167291SKenneth E. Jansen 106*10167291SKenneth E. Jansen zwall=0.0762d00 107*10167291SKenneth E. Jansen do nn=1,nshg ! normalize wNorm 108*10167291SKenneth E. Jansen wn(:)=wNorm(nn,:) 109*10167291SKenneth E. Jansen mag=(wn(1)**2+wn(2)**2+wn(3)**2)**0.5 110*10167291SKenneth E. Jansen if(mag.ne.0) then 111*10167291SKenneth E. Jansen if(((dabs(dabs(x(nn,3))-zwall)).lt.0.000000001d00) 112*10167291SKenneth E. Jansen & .and. (dabs(wn(3)/mag) .lt.0.99)) then 113*10167291SKenneth E. Jansen! logic to trap wall normals in z above failed, possibley in commu? so 114*10167291SKenneth E. Jansen! report it and "fix it" 115*10167291SKenneth E. Jansen write(*,*) 116*10167291SKenneth E. Jansen & "Warning: still screwing up wall Norm, proc ", 117*10167291SKenneth E. Jansen & myrank, ", node ", nn, 118*10167291SKenneth E. Jansen & ", x = (", x(nn,1), x(nn,2), x(nn,3), ")", 119*10167291SKenneth E. Jansen & ", n = (", wn(1), wn(2), wn(3), ")" 120*10167291SKenneth E. Jansen! write(myrank+1000,1234) 121*10167291SKenneth E. Jansen! & nn,x(nn,1),x(nn,2),x(nn,3),wn(1),wn(2),wn(3) 122*10167291SKenneth E. Jansen wn(1)=0 123*10167291SKenneth E. Jansen wn(2)=0 124*10167291SKenneth E. Jansen wn(3)=x(nn,3) 125*10167291SKenneth E. Jansen mag=abs(wn(3)) 126*10167291SKenneth E. Jansen endif 127*10167291SKenneth E. Jansen wNorm(nn,:)=wn(:)/mag 128*10167291SKenneth E. Jansen endif 129*10167291SKenneth E. Jansen enddo 130*10167291SKenneth E. Jansen 131*10167291SKenneth E. Jansen1234 format(i5,6(2x,e12.5)) 132*10167291SKenneth E. Jansen!!DEBUG 133*10167291SKenneth E. Jansen!! dimension u(nshg,n) 134*10167291SKenneth E. Jansen! do j = 1,3 135*10167291SKenneth E. Jansen! do i = 1,nshg 136*10167291SKenneth E. Jansen! u(i,j)=9.876543e21 137*10167291SKenneth E. Jansen! wallBCout(i, j ) = BC( i, j+2) 138*10167291SKenneth E. Jansen! wallBCout(i, j+3) = wNorm(i, j ) 139*10167291SKenneth E. Jansen! enddo 140*10167291SKenneth E. Jansen! enddo 141*10167291SKenneth E. Jansen! call write_restart(myrank,100002,nshg,6,wallBCout,wallBCout) 142*10167291SKenneth E. Jansen!!DEBUG 143*10167291SKenneth E. Jansen 144*10167291SKenneth E. Jansen wNormCalced = .true. 145*10167291SKenneth E. Jansen 146*10167291SKenneth E. Jansen return 147*10167291SKenneth E. Jansen end 148*10167291SKenneth E. Jansen 149*10167291SKenneth E. Jansen subroutine addElemNormal(wNorm, eNorm, nn) 150*10167291SKenneth E. Jansen !Adds contributions from the wall element normal en into the wall 151*10167291SKenneth E. Jansen !normal array wNorm at index nn. 152*10167291SKenneth E. Jansen 153*10167291SKenneth E. Jansen include "common.h" 154*10167291SKenneth E. Jansen 155*10167291SKenneth E. Jansen real*8 :: wNorm(nshg, nsd) 156*10167291SKenneth E. Jansen real*8 :: eNorm(nsd), en(nsd), wn(nsd) 157*10167291SKenneth E. Jansen real*8 :: mag, oDotn 158*10167291SKenneth E. Jansen integer :: nn 159*10167291SKenneth E. Jansen 160*10167291SKenneth E. Jansen wn(:)=wNorm(nn,:) 161*10167291SKenneth E. Jansen mag=(wn(1)**2+wn(2)**2+wn(3)**2)**0.5 162*10167291SKenneth E. Jansen 163*10167291SKenneth E. Jansen if(mag < 1.0e-14) then ! no direction yet so give it this 164*10167291SKenneth E. Jansen wNorm(nn,:) = eNorm(:) 165*10167291SKenneth E. Jansen 166*10167291SKenneth E. Jansen else ! wNorm already has a direction 167*10167291SKenneth E. Jansen wn(:)=wn(:)/mag 168*10167291SKenneth E. Jansen 169*10167291SKenneth E. Jansen mag=(eNorm(1)**2+eNorm(2)**2+eNorm(3)**2)**0.5 170*10167291SKenneth E. Jansen en(:)=eNorm(:)/mag 171*10167291SKenneth E. Jansen 172*10167291SKenneth E. Jansen ! when we are in corners we need to establish a precidence since 173*10167291SKenneth E. Jansen ! averaging will produce irregular results. In this first pass, 174*10167291SKenneth E. Jansen ! let's let the vector with the largest z-normal take precedence. 175*10167291SKenneth E. Jansen oDotn=en(1)*wn(1)+en(2)*wn(2)+en(3)*wn(3) 176*10167291SKenneth E. Jansen if(abs(oDotn) < cornerCosThresh) then ! this is a corner-Don't average 177*10167291SKenneth E. Jansen if(abs(en(3)) > abs(wn(3))) then 178*10167291SKenneth E. Jansen wNorm(nn,:) = eNorm(:) ! overwrite wNorm 179*10167291SKenneth E. Jansen endif ! since no else, wNorm unaffected by weaker z 180*10167291SKenneth E. Jansen ! e.g., for the else, eNorm is ignored 181*10167291SKenneth E. Jansen else ! not a corner so average 182*10167291SKenneth E. Jansen wNorm(nn,:)=wNorm(nn,:) + eNorm(:) 183*10167291SKenneth E. Jansen endif !end if(abs(oDotn) < cornerCosThresh) 184*10167291SKenneth E. Jansen endif !end mag < 1e-14 185*10167291SKenneth E. Jansen 186*10167291SKenneth E. Jansen end subroutine 187*10167291SKenneth E. Jansen 188*10167291SKenneth E. Jansen end module 189*10167291SKenneth E. Jansen 190