110167291SKenneth E. Jansen module wallData !was suctionDuct 210167291SKenneth E. Jansen logical wnormCalced 310167291SKenneth E. Jansen !integer nsuctionface 410167291SKenneth E. Jansen !integer, allocatable :: suctionf(:) 510167291SKenneth E. Jansen 610167291SKenneth E. Jansen !Threshold for determining whether a node is on a corner 710167291SKenneth E. Jansen real*8 :: cornerCosThresh 810167291SKenneth E. Jansen 910167291SKenneth E. Jansen !Wall normal array of size (nshg, 3) 1010167291SKenneth E. Jansen real*8, allocatable :: wnorm(:,:) 1110167291SKenneth E. Jansen contains 1210167291SKenneth E. Jansen 1310167291SKenneth E. Jansen subroutine findWallNorm(x,iBC,ilwork,iper) 1410167291SKenneth E. Jansen 1510167291SKenneth E. Jansen! use wallData 1610167291SKenneth E. Jansen use pointer_data 1710167291SKenneth E. Jansen include "common.h" 1810167291SKenneth E. Jansen include "mpif.h" 1910167291SKenneth E. Jansen 2010167291SKenneth E. Jansen integer iBC(nshg) 2110167291SKenneth E. Jansen real*8 x(numnp,nsd) 2210167291SKenneth E. Jansen integer iper(nshg) 2310167291SKenneth E. Jansen integer ilwork(nlwork) 2410167291SKenneth E. Jansen integer, allocatable :: ienb(:) 2510167291SKenneth E. Jansen real*8, allocatable :: wNormTmp(:,:) 2610167291SKenneth E. Jansen real*8 eNorm(nsd),en(nsd),wn(nsd),aedg(nsd),bedg(nsd) 2710167291SKenneth E. Jansen real*8 mag 2810167291SKenneth E. Jansen! integer isfID 2910167291SKenneth E. Jansen 3010167291SKenneth E. Jansen real*8 wallBCout(nshg, 6) 3110167291SKenneth E. Jansen real*8 BC(nshg,ndofBC) 3210167291SKenneth E. Jansen 3310167291SKenneth E. Jansen cornerCosThresh = 0.75d00 3410167291SKenneth E. Jansen !The number 0.75 is somewhat arbitrary. The thinking is that this 3510167291SKenneth E. Jansen !code is also used for the normal on curved surfaces which will have 3610167291SKenneth E. Jansen !a non unit dot product from elements surrounding a wall vertex but 3710167291SKenneth E. Jansen !acos(0.75) is a pretty big angle. On coarse meshes this number may 3810167291SKenneth E. Jansen !have to be dialed down to get normal on curved walls correct. 3910167291SKenneth E. Jansen 4010167291SKenneth E. Jansen allocate(wNorm(nshg,nsd)) 4110167291SKenneth E. Jansen wNorm = 0 4210167291SKenneth E. Jansen 4310167291SKenneth E. Jansen do iblk=1,nelblb !loop over all the bounday element blocks at current process 4410167291SKenneth E. Jansen npro=lcblkb(1,iblk+1)-lcblkb(1,iblk) 4510167291SKenneth E. Jansen nenbl=lcblkb(6,iblk) 4610167291SKenneth E. Jansen nshl=lcblkb(9,iblk) 4710167291SKenneth E. Jansen allocate(ienb(nshl)) 4810167291SKenneth E. Jansen do i=1,npro ! loop over boundary elements 4910167291SKenneth E. Jansen! isfID=miBCB(iblk)%p(i,2) ! miBCB(2) is the surfID 5010167291SKenneth E. Jansen ienb(1:nshl)=mienb(iblk)%p(i,1:nshl) 5110167291SKenneth E. Jansen do j=1,nenbl ! loop over boundary nodes 5210167291SKenneth E. Jansen nn=ienb(j) !nn is the global index of suction node 5310167291SKenneth E. Jansen if(j.ne.1.and.j.ne.nenbl)then 5410167291SKenneth E. Jansen aedg(:)=x(ienb(j+1),:)-x(nn,:) 5510167291SKenneth E. Jansen bedg(:)=x(ienb(j-1),:)-x(nn,:) 5610167291SKenneth E. Jansen elseif(j.eq.1)then 5710167291SKenneth E. Jansen aedg(:)=x(ienb(j+1),:)-x(nn,:) 5810167291SKenneth E. Jansen bedg(:)=x(ienb(nenbl),:)-x(nn,:) 5910167291SKenneth E. Jansen elseif(j.eq.nenbl)then 6010167291SKenneth E. Jansen aedg(:)=x(ienb(1),:)-x(nn,:) 6110167291SKenneth E. Jansen bedg(:)=x(ienb(j-1),:)-x(nn,:) 6210167291SKenneth E. Jansen endif 6310167291SKenneth E. Jansen eNorm(1)=aedg(2)*bedg(3)-aedg(3)*bedg(2) 6410167291SKenneth E. Jansen eNorm(2)=aedg(3)*bedg(1)-aedg(1)*bedg(3) 6510167291SKenneth E. Jansen eNorm(3)=aedg(1)*bedg(2)-aedg(2)*bedg(1) 6610167291SKenneth E. Jansen 6710167291SKenneth E. Jansen call addElemNormal(wNorm, eNorm, nn) 6810167291SKenneth E. Jansen 6910167291SKenneth E. Jansen enddo !end do j = 1, nenbl 7010167291SKenneth E. Jansen enddo !end do i = 1, npro 7110167291SKenneth E. Jansen deallocate(ienb) 7210167291SKenneth E. Jansen enddo !end do iblk = 1, nelblk 7310167291SKenneth E. Jansen 7410167291SKenneth E. Jansen !Now communicate between parts. Note: there still may be a 7510167291SKenneth E. Jansen !conflict if the boundary edge is on a corner, so a separate array 7610167291SKenneth E. Jansen !needs to be used to allow us to repeat the z-norm comparison. 7710167291SKenneth E. Jansen if(numpe.gt.1) then 7810167291SKenneth E. Jansen allocate(wNormTmp(nshg,nsd)) 7910167291SKenneth E. Jansen wNormTmp = wNorm 8010167291SKenneth E. Jansen call commu(wNormTmp(:,:), ilwork, 3, 'in ') 8110167291SKenneth E. Jansen wNormTmp = wNormTmp - wNorm !undo the addition in commu to just 8210167291SKenneth E. Jansen !get contributions from other processors 8310167291SKenneth E. Jansen 8410167291SKenneth E. Jansen do i = 1,nshg !loop over each node and add the off 8510167291SKenneth E. Jansen wn(:) = wNormTmp(i,:) !processor contribution. If this is 8610167291SKenneth E. Jansen call addElemNormal(wNorm, wn, i) !an interior node, zero gets 8710167291SKenneth E. Jansen enddo !added to zero. 8810167291SKenneth E. Jansen endif 8910167291SKenneth E. Jansen 9010167291SKenneth E. Jansen !It is unclear how to treat periodic boundary conditions, i.e. 9110167291SKenneth E. Jansen !should periodic walls have zero norm, a correct normal for each 9210167291SKenneth E. Jansen !side, or a correct normal for the master. With bc3per commented, 9310167291SKenneth E. Jansen !the wall normal should be calculated as though there is no 9410167291SKenneth E. Jansen !periodic BC. 9510167291SKenneth E. Jansen! call bc3per(iBC,wNorm(:,:),iper,ilwork,3) 9610167291SKenneth E. Jansen 9710167291SKenneth E. Jansen if(numpe.gt.1) call commu(wNorm(:,:),ilwork,3,'out') 9810167291SKenneth E. Jansen 9910167291SKenneth E. Jansen do nn = 1,nshg 10010167291SKenneth E. Jansen wn(:) = wNorm(nn,:) 10110167291SKenneth E. Jansen mag = (wn(1)**2+wn(2)**2+wn(3)**2)**0.5 10210167291SKenneth E. Jansen 10310167291SKenneth E. Jansen if(mag > 0) wNorm(nn,:) = wn(:)/mag 10410167291SKenneth E. Jansen enddo 10510167291SKenneth E. Jansen 10610167291SKenneth E. Jansen zwall=0.0762d00 10710167291SKenneth E. Jansen do nn=1,nshg ! normalize wNorm 10810167291SKenneth E. Jansen wn(:)=wNorm(nn,:) 10910167291SKenneth E. Jansen mag=(wn(1)**2+wn(2)**2+wn(3)**2)**0.5 11010167291SKenneth E. Jansen if(mag.ne.0) then 11110167291SKenneth E. Jansen if(((dabs(dabs(x(nn,3))-zwall)).lt.0.000000001d00) 11210167291SKenneth E. Jansen & .and. (dabs(wn(3)/mag) .lt.0.99)) then 11310167291SKenneth E. Jansen! logic to trap wall normals in z above failed, possibley in commu? so 11410167291SKenneth E. Jansen! report it and "fix it" 11510167291SKenneth E. Jansen write(*,*) 11610167291SKenneth E. Jansen & "Warning: still screwing up wall Norm, proc ", 11710167291SKenneth E. Jansen & myrank, ", node ", nn, 11810167291SKenneth E. Jansen & ", x = (", x(nn,1), x(nn,2), x(nn,3), ")", 11910167291SKenneth E. Jansen & ", n = (", wn(1), wn(2), wn(3), ")" 12010167291SKenneth E. Jansen! write(myrank+1000,1234) 12110167291SKenneth E. Jansen! & nn,x(nn,1),x(nn,2),x(nn,3),wn(1),wn(2),wn(3) 12210167291SKenneth E. Jansen wn(1)=0 12310167291SKenneth E. Jansen wn(2)=0 12410167291SKenneth E. Jansen wn(3)=x(nn,3) 12510167291SKenneth E. Jansen mag=abs(wn(3)) 12610167291SKenneth E. Jansen endif 12710167291SKenneth E. Jansen wNorm(nn,:)=wn(:)/mag 12810167291SKenneth E. Jansen endif 12910167291SKenneth E. Jansen enddo 13010167291SKenneth E. Jansen 13110167291SKenneth E. Jansen1234 format(i5,6(2x,e12.5)) 13210167291SKenneth E. Jansen!!DEBUG 13310167291SKenneth E. Jansen!! dimension u(nshg,n) 13410167291SKenneth E. Jansen! do j = 1,3 13510167291SKenneth E. Jansen! do i = 1,nshg 13610167291SKenneth E. Jansen! u(i,j)=9.876543e21 13710167291SKenneth E. Jansen! wallBCout(i, j ) = BC( i, j+2) 13810167291SKenneth E. Jansen! wallBCout(i, j+3) = wNorm(i, j ) 13910167291SKenneth E. Jansen! enddo 14010167291SKenneth E. Jansen! enddo 14110167291SKenneth E. Jansen! call write_restart(myrank,100002,nshg,6,wallBCout,wallBCout) 14210167291SKenneth E. Jansen!!DEBUG 14310167291SKenneth E. Jansen 14410167291SKenneth E. Jansen wNormCalced = .true. 14510167291SKenneth E. Jansen 14610167291SKenneth E. Jansen return 147*13c4f35aSKenneth E. Jansen end subroutine 14810167291SKenneth E. Jansen 14910167291SKenneth E. Jansen subroutine addElemNormal(wNorm, eNorm, nn) 15010167291SKenneth E. Jansen !Adds contributions from the wall element normal en into the wall 15110167291SKenneth E. Jansen !normal array wNorm at index nn. 15210167291SKenneth E. Jansen 15310167291SKenneth E. Jansen include "common.h" 15410167291SKenneth E. Jansen 15510167291SKenneth E. Jansen real*8 :: wNorm(nshg, nsd) 15610167291SKenneth E. Jansen real*8 :: eNorm(nsd), en(nsd), wn(nsd) 15710167291SKenneth E. Jansen real*8 :: mag, oDotn 15810167291SKenneth E. Jansen integer :: nn 15910167291SKenneth E. Jansen 16010167291SKenneth E. Jansen wn(:)=wNorm(nn,:) 16110167291SKenneth E. Jansen mag=(wn(1)**2+wn(2)**2+wn(3)**2)**0.5 16210167291SKenneth E. Jansen 16310167291SKenneth E. Jansen if(mag < 1.0e-14) then ! no direction yet so give it this 16410167291SKenneth E. Jansen wNorm(nn,:) = eNorm(:) 16510167291SKenneth E. Jansen 16610167291SKenneth E. Jansen else ! wNorm already has a direction 16710167291SKenneth E. Jansen wn(:)=wn(:)/mag 16810167291SKenneth E. Jansen 16910167291SKenneth E. Jansen mag=(eNorm(1)**2+eNorm(2)**2+eNorm(3)**2)**0.5 17010167291SKenneth E. Jansen en(:)=eNorm(:)/mag 17110167291SKenneth E. Jansen 17210167291SKenneth E. Jansen ! when we are in corners we need to establish a precidence since 17310167291SKenneth E. Jansen ! averaging will produce irregular results. In this first pass, 17410167291SKenneth E. Jansen ! let's let the vector with the largest z-normal take precedence. 17510167291SKenneth E. Jansen oDotn=en(1)*wn(1)+en(2)*wn(2)+en(3)*wn(3) 17610167291SKenneth E. Jansen if(abs(oDotn) < cornerCosThresh) then ! this is a corner-Don't average 17710167291SKenneth E. Jansen if(abs(en(3)) > abs(wn(3))) then 17810167291SKenneth E. Jansen wNorm(nn,:) = eNorm(:) ! overwrite wNorm 17910167291SKenneth E. Jansen endif ! since no else, wNorm unaffected by weaker z 18010167291SKenneth E. Jansen ! e.g., for the else, eNorm is ignored 18110167291SKenneth E. Jansen else ! not a corner so average 18210167291SKenneth E. Jansen wNorm(nn,:)=wNorm(nn,:) + eNorm(:) 18310167291SKenneth E. Jansen endif !end if(abs(oDotn) < cornerCosThresh) 18410167291SKenneth E. Jansen endif !end mag < 1e-14 18510167291SKenneth E. Jansen 18610167291SKenneth E. Jansen end subroutine 18710167291SKenneth E. Jansen 18810167291SKenneth E. Jansen end module 18910167291SKenneth E. Jansen 190