159599516SKenneth E. Jansen subroutine genBC (iBC, BC, x, ilwork, iper) 259599516SKenneth E. Jansenc 359599516SKenneth E. Jansenc---------------------------------------------------------------------- 459599516SKenneth E. Jansenc This routine generates the essential prescribed boundary conditions. 559599516SKenneth E. Jansenc 659599516SKenneth E. Jansenc input: 759599516SKenneth E. Jansenc iBC (nshg) : boundary condition code 859599516SKenneth E. Jansenc nBC (nshg) : boundary condition mapping array 959599516SKenneth E. Jansenc 1059599516SKenneth E. Jansenc output: 1159599516SKenneth E. Jansenc BC (nshg,ndofBC) : The constraint data for prescribed BC 1259599516SKenneth E. Jansenc 1359599516SKenneth E. Jansenc 1459599516SKenneth E. Jansenc Note: genBC1 reduces the input data for the velocity. In the 1559599516SKenneth E. Jansenc case of varying velocity direction in the generation, the 1659599516SKenneth E. Jansenc results may not be correct. (since a linearity assumption is 1759599516SKenneth E. Jansenc made in the generation). 1859599516SKenneth E. Jansenc 1959599516SKenneth E. Jansenc 2059599516SKenneth E. Jansenc Farzin Shakib, Spring 1986. 2159599516SKenneth E. Jansenc Zdenek Johan, Winter 1991. (Fortran 90) 2259599516SKenneth E. Jansenc---------------------------------------------------------------------- 2359599516SKenneth E. Jansenc 2459599516SKenneth E. Jansen use slpw 2559599516SKenneth E. Jansen use readarrays ! used to access BCinp, nBC 2659599516SKenneth E. Jansen use specialBC ! filling acs here 2759599516SKenneth E. Jansen include "common.h" 2859599516SKenneth E. Jansenc 2959599516SKenneth E. Jansen dimension iBC(nshg), nsurf(nshg), 3059599516SKenneth E. Jansen & BC(nshg,ndofBC), 3159599516SKenneth E. Jansen & x(numnp,nsd), ilwork(nlwork), 3259599516SKenneth E. Jansen & iper(nshg) 3359599516SKenneth E. Jansenc 3459599516SKenneth E. Jansenc BCinp for each point has: 3559599516SKenneth E. Jansenc D T P c11 c12 c13 M1 c21 c22 c23 M2 theta S1 S2 S3... 3659599516SKenneth E. Jansenc 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15... 3759599516SKenneth E. Jansenc Remember, ndof=nsd+2+nsclr 3859599516SKenneth E. Jansenc 3959599516SKenneth E. Jansenc Arrays in the following 1 line are now dimensioned in readnblk 4059599516SKenneth E. Jansenc dimension BCinp(numpbc,ndof+7) 4159599516SKenneth E. Jansenc 4259599516SKenneth E. Jansen dimension BCtmp(nshg,ndof+7) 4359599516SKenneth E. Jansenc 4459599516SKenneth E. Jansenc ndof+7= 3(thermos) + (nsd-1)*(nsd+1) + nscalars + 1 (theta) 4559599516SKenneth E. Jansenc #vect *(vec dir +mag) 4659599516SKenneth E. Jansenc 4759599516SKenneth E. Jansenc.... ---------------------------> Input <--------------------------- 4859599516SKenneth E. Jansenc 4959599516SKenneth E. Jansenc.... convert boundary condition data 5059599516SKenneth E. Jansenc 5159599516SKenneth E. Jansen BCtmp = zero 5259599516SKenneth E. Jansenc 5359599516SKenneth E. Jansen if(numpbc.ne.0) then 5459599516SKenneth E. Jansen do i = 1, ndof+7 5559599516SKenneth E. Jansen where (nBC(:) .ne. 0) BCtmp(:,i) = BCinp(nBC(:),i) 5659599516SKenneth E. Jansen enddo 5759599516SKenneth E. Jansen endif 58*f538fcd7SKenneth E. Jansen deallocate(BCinp) 5959599516SKenneth E. Jansen 6059599516SKenneth E. Jansenc 6159599516SKenneth E. Jansen if(any(BCtmp(:,12).ne.0)) then 6259599516SKenneth E. Jansen iabc=1 6359599516SKenneth E. Jansen allocate (acs(nshg,2)) 6459599516SKenneth E. Jansen where (btest(iBC,10)) 6559599516SKenneth E. Jansen acs(:,1) = cos(BCtmp(:,12)) 6659599516SKenneth E. Jansen acs(:,2) = sin(BCtmp(:,12)) 6759599516SKenneth E. Jansen endwhere 6859599516SKenneth E. Jansen endif 6959599516SKenneth E. Jansen 7059599516SKenneth E. Jansenc 7159599516SKenneth E. Jansenc.... ----------------------> Wall Normals <-------------------------- 7259599516SKenneth E. Jansenc (calculate the normal and adjust BCinp to the true normal as needed) 7359599516SKenneth E. Jansenc 749d66a07dSKenneth E. Jansen!needed either way if(navier.eq.1)then 7559599516SKenneth E. Jansen call genwnm (iBC, BCtmp, x, ilwork, iper, nsurf) 769d66a07dSKenneth E. Jansen!needed either way endif 7759599516SKenneth E. Jansenc determine the first point off the wall for each wall node 789d66a07dSKenneth E. Jansen!needed either way if(navier.eq.1)then 7959599516SKenneth E. Jansen call genotwn (x,BCtmp, iBC, nsurf) 809d66a07dSKenneth E. Jansen!needed either way endif 8159599516SKenneth E. Jansenc.... ------------------------> Conversion <------------------------- 8259599516SKenneth E. Jansenc 8359599516SKenneth E. Jansenc.... convert the input boundary conditions to condensed version 8459599516SKenneth E. Jansenc 8559599516SKenneth E. Jansen BC = zero 8659599516SKenneth E. Jansenc 87513954efSKenneth E. Jansen if(myrank.eq.0) write(*,*) 'Navier is set to ', navier 8859599516SKenneth E. Jansen if(navier.eq.1)then ! zero navier means Euler simulation 8959599516SKenneth E. Jansen call genBC1 (BCtmp, iBC, BC) 905124a526SKenneth E. Jansen else !enabling for IC code now 915124a526SKenneth E. Jansenc elseif(matflg(1,1).eq.0)then ! compressible code 9259599516SKenneth E. Jansen allocate(BCtmpg(nshg,ndof+7)) 9359599516SKenneth E. Jansen allocate(BCg(nshg,ndofBC)) 9459599516SKenneth E. Jansen allocate(iBCg(nshg)) 9559599516SKenneth E. Jansen BCtmpg=BCtmp 9659599516SKenneth E. Jansen iBCg=iBC 9759599516SKenneth E. Jansen call genBC1 (BCtmp, iBC, BC) 9859599516SKenneth E. Jansenc... genBC1 convert BCtmp to BC 9959599516SKenneth E. Jansen BCg=BC 10059599516SKenneth E. Jansen icdg=icd 10159599516SKenneth E. Jansenc... find slip wall 10259599516SKenneth E. Jansen call findslpw(x,ilwork,iper,iBC) 10359599516SKenneth E. Jansenc... apply slip wall condition to wall nodes 10459599516SKenneth E. Jansen do i=1,nslpwnd 10559599516SKenneth E. Jansen nn=idxslpw(i) 10659599516SKenneth E. Jansen call slpwBC(mpslpw(nn,1),mpslpw(nn,2),iBCg(nn), 10759599516SKenneth E. Jansen & BCg(nn,:), BCtmpg(nn,:), 10859599516SKenneth E. Jansen & iBC(nn), BC(nn,:), 10959599516SKenneth E. Jansen & wlnorm(nn,:,:) ) 11059599516SKenneth E. Jansen enddo 11159599516SKenneth E. Jansen icd=icdg 112*f538fcd7SKenneth E. Jansen deallocate(idxslpw) 113*f538fcd7SKenneth E. Jansen deallocate(BCg) 114*f538fcd7SKenneth E. Jansen deallocate(iBCg) 115*f538fcd7SKenneth E. Jansen deallocate(BCtmpg) 116*f538fcd7SKenneth E. Jansen deallocate(mpslpw) 117*f538fcd7SKenneth E. Jansen deallocate(wlnorm) 1185124a526SKenneth E. Jansen! else 1195124a526SKenneth E. Jansen! if(myrank.eq.0) write(*,*) 'Incompressible code not able to do inviscid at this time' 12059599516SKenneth E. Jansen endif 12159599516SKenneth E. Jansen 12259599516SKenneth E. Jansen 12359599516SKenneth E. Jansenc 12459599516SKenneth E. Jansenc.... ---------------------------> Echo <---------------------------- 12559599516SKenneth E. Jansenc 12659599516SKenneth E. Jansenc.... echo the input data 12759599516SKenneth E. Jansenc 12859599516SKenneth E. Jansen if (necho .lt. 3) then 12959599516SKenneth E. Jansen nn = 0 13059599516SKenneth E. Jansen do n = 1, nshg 13159599516SKenneth E. Jansen if (nBC(n) .ne. 0) then 13259599516SKenneth E. Jansen nn = nn + 1 13359599516SKenneth E. Jansen if(mod(nn,50).eq.1) 13459599516SKenneth E. Jansen & write(iecho,1000)ititle,(j,j=1,ndofBC) 13559599516SKenneth E. Jansen write (iecho,1100) n, (BC(n,i),i=1,ndofBC) 13659599516SKenneth E. Jansen endif 13759599516SKenneth E. Jansen enddo 13859599516SKenneth E. Jansen endif 13959599516SKenneth E. Jansenc 14059599516SKenneth E. Jansenc.... return 14159599516SKenneth E. Jansenc 14259599516SKenneth E. Jansen return 14359599516SKenneth E. Jansenc 14459599516SKenneth E. Jansen 1000 format(a80,//, 14559599516SKenneth E. Jansen &' P r e s c r i b e d B o u n d a r y C o n d i t i o n s',//, 14659599516SKenneth E. Jansen & ' Node ',/, 14759599516SKenneth E. Jansen & ' Number ',5x,6('BC',i1,:,10x)) 14859599516SKenneth E. Jansen 1100 format(1p,2x,i5,3x,6(e12.5,1x)) 14959599516SKenneth E. Jansenc 15059599516SKenneth E. Jansen end 15159599516SKenneth E. Jansen 15259599516SKenneth E. Jansen 15359599516SKenneth E. Jansen 15459599516SKenneth E. Jansen 15559599516SKenneth E. Jansen 15659599516SKenneth E. Jansen 15759599516SKenneth E. Jansen 15859599516SKenneth E. Jansen 15959599516SKenneth E. Jansen 16059599516SKenneth E. Jansen 16159599516SKenneth E. Jansen subroutine genwnm (iBC, BCtmp, x, ilwork, iper, nsurf) 16259599516SKenneth E. Jansenc---------------------------------------------------------------------- 16359599516SKenneth E. Jansenc This routine generates the normal to a wall 16459599516SKenneth E. Jansenc 16559599516SKenneth E. Jansenc input: 16659599516SKenneth E. Jansenc iBC (nshg) : boundary condition code 16759599516SKenneth E. Jansenc nBC (nshg) : boundary condition mapping array 16859599516SKenneth E. Jansenc 16959599516SKenneth E. Jansenc output: 17059599516SKenneth E. Jansenc BCtmp (nshg,ndof+6) : The constraint data for prescribed BC 17159599516SKenneth E. Jansenc 17259599516SKenneth E. Jansenc 17359599516SKenneth E. Jansenc---------------------------------------------------------------------- 17459599516SKenneth E. Jansenc 17559599516SKenneth E. Jansen use turbSA 17659599516SKenneth E. Jansen use pointer_data ! used for mienb, mibcb 17759599516SKenneth E. Jansen include "common.h" 17859599516SKenneth E. Jansen include "mpif.h" 17959599516SKenneth E. Jansenc 18059599516SKenneth E. Jansen character*20 fname1, fmt1 18159599516SKenneth E. Jansen character*5 cname 18259599516SKenneth E. Jansen dimension iBC(nshg), iper(nshg), 18359599516SKenneth E. Jansen & x(numnp,nsd), ilwork(nlwork) 18459599516SKenneth E. Jansenc 18559599516SKenneth E. Jansen dimension BCtmpSAV(nshg,ndof+7) 18659599516SKenneth E. Jansen dimension BCtmp(nshg,ndof+7), fBC(nshg,ndofBC), 18759599516SKenneth E. Jansen & e1(3), e2(3), 18859599516SKenneth E. Jansen & elnrm(3), asum(numnp) 18959599516SKenneth E. Jansenc 19059599516SKenneth E. Jansen integer sid, nsidg 19159599516SKenneth E. Jansen integer nsurf(nshg), ivec(nsd) 19259599516SKenneth E. Jansen logical :: firstvisit(nshg) 19359599516SKenneth E. Jansen real*8 BCvecs(2,nsd) 19459599516SKenneth E. Jansen integer, allocatable :: ienb(:) 19559599516SKenneth E. Jansen dimension wnmdb(nshg,nsd) 19659599516SKenneth E. Jansenc 19759599516SKenneth E. Jansenc wnrm is dimensioned nshg but the math is only done for straight sided 19859599516SKenneth E. Jansenc elements at this point so wnrm will not be calculated for the hierarchic 19959599516SKenneth E. Jansenc modes. Note that the wall model creates a p.w. linear representation 20059599516SKenneth E. Jansenc only at this time. 20159599516SKenneth E. Jansenc 20259599516SKenneth E. Jansen allocate ( wnrm(nshg,3) ) 20359599516SKenneth E. Jansenc 20459599516SKenneth E. Jansenc.... ----------------------> Wall Normals <-------------------------- 20559599516SKenneth E. Jansenc (calculate the normal and adjust BCinp to the true normal as needed) 20659599516SKenneth E. Jansenc 20759599516SKenneth E. Jansenc 20859599516SKenneth E. Jansen asum = zero 20959599516SKenneth E. Jansen wnrm = zero 21059599516SKenneth E. Jansen 21159599516SKenneth E. Jansenc 21259599516SKenneth E. Jansenc.... Save a copy of BCtmp so that after we calculate the normals we 21359599516SKenneth E. Jansenc can recover the comp3 information. 21459599516SKenneth E. Jansenc 21559599516SKenneth E. Jansen BCtmpSAV=BCtmp 21659599516SKenneth E. Jansenc 21759599516SKenneth E. Jansenc Count out the number of surface ID's on-processor, and map them 21859599516SKenneth E. Jansen call gensidcount(nsidg) 21959599516SKenneth E. Jansen 22059599516SKenneth E. Jansenc 22159599516SKenneth E. Jansen if(nsidg.gt.0) then ! if there are any surfID's 22259599516SKenneth E. Jansen nsurf(:) = 0 22359599516SKenneth E. Jansen do k = 1, nsidg ! loop over Surface ID's 22459599516SKenneth E. Jansen sid = sidmapg(k) 22559599516SKenneth E. Jansen firstvisit(:)=.true. 22659599516SKenneth E. Jansen wnrm(:,1:3)=zero 22759599516SKenneth E. Jansen do iblk=1, nelblb ! loop over boundary element blocks 22859599516SKenneth E. Jansen npro = lcblkb(1,iblk+1)-lcblkb(1,iblk) 22959599516SKenneth E. Jansen nenbl = lcblkb(6,iblk) 23059599516SKenneth E. Jansen nshl = lcblkb(9,iblk) 23159599516SKenneth E. Jansen allocate( ienb(nshl) ) 23259599516SKenneth E. Jansen do i = 1, npro ! loop over boundary elements 23359599516SKenneth E. Jansen iBCB1=miBCB(iblk)%p(i,1) 23459599516SKenneth E. Jansen iBCB2=miBCB(iblk)%p(i,2) 23559599516SKenneth E. Jansen ienb(1:nshl)=mienb(iblk)%p(i,1:nshl) 23659599516SKenneth E. Jansenc don't bother with elements that aren't on modeled surfaces 23759599516SKenneth E. Jansenc if ( not (wall set and traction set) ) 23859599516SKenneth E. Jansen if (.not.(btest(iBCB1,2).and.btest(iBCB1,4))) 23959599516SKenneth E. Jansen & cycle 24059599516SKenneth E. Jansenc don't bother with elements that don't lie on the current surface 24159599516SKenneth E. Jansen if (iBCB2.ne.sid) cycle 24259599516SKenneth E. Jansenc 24359599516SKenneth E. Jansenc.... calculate this element's area-weighted normal vector 24459599516SKenneth E. Jansenc 24559599516SKenneth E. Jansen e1 = x(ienb(2),:)-x(ienb(1),:) 24659599516SKenneth E. Jansen e2 = x(ienb(3),:)-x(ienb(1),:) 24759599516SKenneth E. Jansen elnrm(1) = e1(2)*e2(3)-e1(3)*e2(2) 24859599516SKenneth E. Jansen elnrm(2) = e1(3)*e2(1)-e1(1)*e2(3) 24959599516SKenneth E. Jansen elnrm(3) = e1(1)*e2(2)-e1(2)*e2(1) 25059599516SKenneth E. Jansenc Tetrahedral elements have negative volumes in phastaI, so 25159599516SKenneth E. Jansenc the normals calculated from the boundary faces must be inverted 25259599516SKenneth E. Jansenc to point into the fluid 25359599516SKenneth E. Jansen if(nenbl.eq.3) elnrm(:)=-elnrm(:) 25459599516SKenneth E. Jansenc 25559599516SKenneth E. Jansenc.... add area-weighted normals to the nodal tallies for this surface 25659599516SKenneth E. Jansenc 25759599516SKenneth E. Jansen do j = 1, nenbl ! loop over elt boundary nodes 25859599516SKenneth E. Jansen nn=ienb(j) ! global node number 25959599516SKenneth E. Jansen if(firstvisit(nn)) then 26059599516SKenneth E. Jansen firstvisit(nn)=.false. 26159599516SKenneth E. Jansen nsurf(nn)=nsurf(nn)+1 26259599516SKenneth E. Jansen if(nsurf(nn).eq.1) BCtmp(nn,4:6)=zero 26359599516SKenneth E. Jansen if(nsurf(nn).eq.2) BCtmp(nn,8:10)=zero 26459599516SKenneth E. Jansen endif 26559599516SKenneth E. Jansen wnrm(nn,:)=wnrm(nn,:)+elnrm 26659599516SKenneth E. Jansen enddo ! loop over elt boundary nodes 26759599516SKenneth E. Jansen enddo ! end loop over boundary elements in block 26859599516SKenneth E. Jansen deallocate(ienb) 26959599516SKenneth E. Jansen enddo ! end loop over boundary element blocks 27059599516SKenneth E. Jansenc Now we have all of this surface's contributions to wall normals 27159599516SKenneth E. Jansenc for all nodes, along with an indication of how many surfaces 27259599516SKenneth E. Jansenc each node has encountered so far. Contributions from other processors 27359599516SKenneth E. Jansenc should now be accumulated for this surface 27459599516SKenneth E. Jansenc 27559599516SKenneth E. Jansenc axisymm BC's need BC (and we have not built it yet) so we need to create 27659599516SKenneth E. Jansenc the entries it needs. 27759599516SKenneth E. Jansenc 27859599516SKenneth E. Jansen if(iabc==1) then 27959599516SKenneth E. Jansen where (btest(iBC,10)) 28059599516SKenneth E. Jansen fBC(:,1) = cos(BCtmp(:,12)) 28159599516SKenneth E. Jansen fBC(:,2) = sin(BCtmp(:,12)) 28259599516SKenneth E. Jansen endwhere 28359599516SKenneth E. Jansen 28459599516SKenneth E. Jansenc before the commu we need to rotate the residual vector for axisymmetric 28559599516SKenneth E. Jansenc boundary conditions (so that off processor periodicity is a dof add instead 28659599516SKenneth E. Jansenc of a dof combination). Take care of all nodes now so periodicity, like 28759599516SKenneth E. Jansenc commu is a simple dof add. 28859599516SKenneth E. Jansen call rotabc(wnrm, iBC, 'in ') 28959599516SKenneth E. Jansen endif 29059599516SKenneth E. Jansen 29159599516SKenneth E. Jansen if (numpe.gt.1) then 29259599516SKenneth E. Jansenc.... add areas and norms contributed from other processors 29359599516SKenneth E. Jansen call commu (wnrm, ilwork, 3, 'in ') 29459599516SKenneth E. Jansen endif 29559599516SKenneth E. Jansenc.... account for periodicity and axisymmetry 29659599516SKenneth E. Jansen call bc3per(iBC,wnrm, iper,ilwork, 3) 29759599516SKenneth E. Jansenc at this point the master has all the information (slaves are zeroed and 29859599516SKenneth E. Jansenc waiting to be told what the master has...lets do that). 29959599516SKenneth E. Jansenc 30059599516SKenneth E. Jansenc.... local periodic (and axisymmetric) boundary conditions (no communications) 30159599516SKenneth E. Jansen wnmdb=wnrm 30259599516SKenneth E. Jansen do i = 1,numnp ! only use the vertices in the normal calc 30359599516SKenneth E. Jansen wnrm(i,:) = wnrm(iper(i),:) 30459599516SKenneth E. Jansen enddo 30559599516SKenneth E. Jansen wnmdb=wnrm 30659599516SKenneth E. Jansen if (numpe.gt.1) then 30759599516SKenneth E. Jansenc.... tell other processors the resulting (and now complete) sums 30859599516SKenneth E. Jansen call commu (wnrm, ilwork, 3, 'out') 30959599516SKenneth E. Jansen endif 31059599516SKenneth E. Jansenc Axisymmetric slaves need to be rotated back 31159599516SKenneth E. Jansen if(iabc==1) then !are there any axisym bc's 31259599516SKenneth E. Jansen call rotabc(wnrm, iBC, 'out') 31359599516SKenneth E. Jansen endif 31459599516SKenneth E. Jansenc Now all nodes have all the normal contributions for this surface, 31559599516SKenneth E. Jansenc including those from off-processor and periodic nodes. 31659599516SKenneth E. Jansenc We distribute these summed vectors to the proper slots in BCtmp, 31759599516SKenneth E. Jansenc according to how many surfaces each node has seen so far 31859599516SKenneth E. Jansen do nn = 1, nshg 31959599516SKenneth E. Jansen if(nsurf(nn).eq.1) 32059599516SKenneth E. Jansen & BCtmp(nn,4:6)=BCtmp(nn,4:6)+wnrm(nn,:) 32159599516SKenneth E. Jansen if(nsurf(nn).eq.2) 32259599516SKenneth E. Jansen & BCtmp(nn,8:10)=BCtmp(nn,8:10)+wnrm(nn,:) 32359599516SKenneth E. Jansen if(nsurf(nn).gt.2) 32459599516SKenneth E. Jansen & BCtmp(nn,4:6)=BCtmp(nn,4:6)+wnrm(nn,:) 32559599516SKenneth E. Jansen enddo 32659599516SKenneth E. Jansenc That's all for this surface; move on to the next 32759599516SKenneth E. Jansen enddo ! end loop over surface ID's 3286b966dd8SCameron Smith deallocate( sidmapg ) 32959599516SKenneth E. Jansen 33059599516SKenneth E. Jansenc 33159599516SKenneth E. Jansenc.... complete the averaging, adjust iBC, adjust BCtmp 33259599516SKenneth E. Jansenc 33359599516SKenneth E. Jansen wnrm(:,1:3)=zero 33459599516SKenneth E. Jansen do nn = 1, numnp ! loop over all nodes 33559599516SKenneth E. Jansenc leave nodes without wall-modeled surfaces unchanged 33659599516SKenneth E. Jansen if(nsurf(nn).eq.0) cycle 33759599516SKenneth E. Jansenc 33859599516SKenneth E. Jansenc mark this as a node with comp3 33959599516SKenneth E. Jansenc 34059599516SKenneth E. Jansen ikp=0 34159599516SKenneth E. Jansen if(ibits(iBC(nn),3,3).eq.7 ) ikp=1 34259599516SKenneth E. Jansenc if(ibits(ibc(nn),3,3).eq.7 .and. BCtmp(nn,7).eq.zero) cycle 34359599516SKenneth E. Jansenc find out which velocity BC's were set by the user, and cancel them 34459599516SKenneth E. Jansen ixset=ibits(iBC(nn),3,1) 34559599516SKenneth E. Jansen iyset=ibits(iBC(nn),4,1) 34659599516SKenneth E. Jansen izset=ibits(iBC(nn),5,1) 34759599516SKenneth E. Jansen iBC(nn)=iBC(nn)-ixset*8-iyset*16-izset*32 34859599516SKenneth E. Jansenc 34959599516SKenneth E. Jansenc save this stripped iBC for later un-fixing 35059599516SKenneth E. Jansenc 35159599516SKenneth E. Jansen iBCSAV=iBC(nn) 35259599516SKenneth E. Jansenc 35359599516SKenneth E. Jansen if(abs(itwmod).eq.1) then ! slip velocity wall-model 35459599516SKenneth E. Jansenc If we're using the slip-velocity wall-model, then the velocity 35559599516SKenneth E. Jansenc boundary condition for this node will depend on how many modeled 35659599516SKenneth E. Jansenc surfaces share it... 35759599516SKenneth E. Jansen if(nsurf(nn).eq.1) then ! 1 modeled wall 35859599516SKenneth E. Jansenc If this node is part of only one modeled wall, then the component 35959599516SKenneth E. Jansenc of the velocity normal to the surface is set to zero. In this case 36059599516SKenneth E. Jansenc only the first vector of BCtmp received normal contributions 36159599516SKenneth E. Jansen iBC(nn)=iBC(nn)+8 ! assume normal is x-dominated first 36259599516SKenneth E. Jansen wnrm(nn,:)=BCtmp(nn,4:6) 36359599516SKenneth E. Jansen if(abs(wnrm(nn,3)).gt.abs(wnrm(nn,2)))then ! z beats y 36459599516SKenneth E. Jansen if(abs(wnrm(nn,3)).gt.abs(wnrm(nn,1)))then ! z beats x 36559599516SKenneth E. Jansen iBC(nn)=iBC(nn)+24 36659599516SKenneth E. Jansen endif ! z beats x 36759599516SKenneth E. Jansen endif ! z beats y 36859599516SKenneth E. Jansen if(abs(wnrm(nn,2)).ge.abs(wnrm(nn,3)))then ! y beats z 36959599516SKenneth E. Jansen if(abs(wnrm(nn,2)).gt.abs(wnrm(nn,1)))then ! y beats x 37059599516SKenneth E. Jansen iBC(nn)=iBC(nn)+8 37159599516SKenneth E. Jansen endif ! y beats x 37259599516SKenneth E. Jansen endif ! y beats z !(adjusted iBC) 37359599516SKenneth E. Jansen BCtmp(nn,7)=zero 37459599516SKenneth E. Jansen else if(nsurf(nn).eq.2) then 37559599516SKenneth E. Jansenc If this node is shared by two modeled walls, then each wall 37659599516SKenneth E. Jansenc provides a normal vector along which the velocity must be zero. 37759599516SKenneth E. Jansenc This leaves only one "free" direction, along which the flow is nonzero. 37859599516SKenneth E. Jansenc The two normal vectors define a plane. Any pair of non-parallel 37959599516SKenneth E. Jansenc vectors in this plane can also be specified, leaving the same free 38059599516SKenneth E. Jansenc direction. Area-weighted average normal vectors for the two surfaces 38159599516SKenneth E. Jansenc sharing this node have been stored in BCtmp(4:6) and BCtmp(8:10) 38259599516SKenneth E. Jansenc We normalize the first of these, and then orthogonalize the second 38359599516SKenneth E. Jansenc against the first. After then normalizing the second, we choose which 38459599516SKenneth E. Jansenc cartesian direction dominates each of the vectors, and adjust iBC 38559599516SKenneth E. Jansenc and BCtmp accordingly 38659599516SKenneth E. Jansen e1=BCtmp(nn,4:6) 38759599516SKenneth E. Jansen wmag=e1(1)*e1(1)+e1(2)*e1(2)+e1(3)*e1(3) 38859599516SKenneth E. Jansen wmag=1./sqrt(wmag) 38959599516SKenneth E. Jansen e1=e1*wmag ! first vector is normalized 39059599516SKenneth E. Jansenc 39159599516SKenneth E. Jansen e2=BCtmp(nn,8:10) 39259599516SKenneth E. Jansen wmag=e2(1)*e1(1)+e2(2)*e1(2)+e2(3)*e1(3) ! wmag=e2.n1 39359599516SKenneth E. Jansen e2=e2-wmag*e1 ! second vector is orthogonalized 39459599516SKenneth E. Jansenc 39559599516SKenneth E. Jansen wmag=e2(1)*e2(1)+e2(2)*e2(2)+e2(3)*e2(3) 39659599516SKenneth E. Jansen wmag=1./sqrt(wmag) 39759599516SKenneth E. Jansen e2=e2*wmag ! second vector is normalized 39859599516SKenneth E. Jansenc 39959599516SKenneth E. Jansen ! idom tells us which component is currently dominant 40059599516SKenneth E. Jansen ! ivec(n) tells us which vector is dominated by comp n 40159599516SKenneth E. Jansen ivec(:)=0 ! initialize 40259599516SKenneth E. Jansen idom=1 ! assume x-comp dominates e1 40359599516SKenneth E. Jansen bigcomp=abs(e1(1)) 40459599516SKenneth E. Jansen ivec(idom)=1 40559599516SKenneth E. Jansen do i = 2, nsd 40659599516SKenneth E. Jansen if(abs(e1(i)).gt.bigcomp) then 40759599516SKenneth E. Jansen ivec(idom)=0 40859599516SKenneth E. Jansen bigcomp=abs(e1(i)) 40959599516SKenneth E. Jansen idom=i 41059599516SKenneth E. Jansen ivec(i)=1 41159599516SKenneth E. Jansen endif 41259599516SKenneth E. Jansen enddo 41359599516SKenneth E. Jansen if(idom.ne.1) then 41459599516SKenneth E. Jansen idom=1 ! assume x-comp dominates e2 41559599516SKenneth E. Jansen else 41659599516SKenneth E. Jansen idom=3 ! assume z-comp dominates e2 41759599516SKenneth E. Jansen endif 41859599516SKenneth E. Jansen bigcomp=abs(e2(idom)) 41959599516SKenneth E. Jansen 42059599516SKenneth E. Jansen ivec(idom)=2 42159599516SKenneth E. Jansen do i = 1, nsd 42259599516SKenneth E. Jansen if(abs(e2(i)).gt.bigcomp) then 42359599516SKenneth E. Jansen if(ivec(i).eq.1) cycle 42459599516SKenneth E. Jansen ivec(idom)=0 42559599516SKenneth E. Jansen bigcomp=abs(e2(i)) 42659599516SKenneth E. Jansen idom=i 42759599516SKenneth E. Jansen ivec(i)=2 42859599516SKenneth E. Jansen endif 42959599516SKenneth E. Jansen enddo 43059599516SKenneth E. Jansen ! now we know which components dominate each vector 43159599516SKenneth E. Jansen ixset=0 ! 43259599516SKenneth E. Jansen iyset=0 ! initialize 43359599516SKenneth E. Jansen izset=0 ! 43459599516SKenneth E. Jansen if(ivec(1).ne.0) ixset=1 43559599516SKenneth E. Jansen if(ivec(2).ne.0) iyset=1 43659599516SKenneth E. Jansen if(ivec(3).ne.0) izset=1 43759599516SKenneth E. Jansen ncomp=ixset+iyset+izset 43859599516SKenneth E. Jansen if(ncomp.ne.2) write(*,*) 'WARNING: TROUBLE IN GENBC' 43959599516SKenneth E. Jansen BCvecs(1,1:3)=e1(:) 44059599516SKenneth E. Jansen BCvecs(2,1:3)=e2(:) 44159599516SKenneth E. Jansen if((ixset.eq.1).and.(iyset.eq.1)) then 44259599516SKenneth E. Jansen BCtmp(nn,4:6)=BCvecs(ivec(1),1:3) 44359599516SKenneth E. Jansen BCtmp(nn,8:10)=BCvecs(ivec(2),1:3) 44459599516SKenneth E. Jansen else if((ixset.eq.1).and.(izset.eq.1)) then 44559599516SKenneth E. Jansen BCtmp(nn,4:6)=BCvecs(ivec(1),1:3) 44659599516SKenneth E. Jansen BCtmp(nn,8:10)=BCvecs(ivec(3),1:3) 44759599516SKenneth E. Jansen else if((iyset.eq.1).and.(izset.eq.1)) then 44859599516SKenneth E. Jansen BCtmp(nn,4:6)=BCvecs(ivec(2),1:3) 44959599516SKenneth E. Jansen BCtmp(nn,8:10)=BCvecs(ivec(3),1:3) 45059599516SKenneth E. Jansen endif 45159599516SKenneth E. Jansen iBC(nn)=iBC(nn)+ixset*8+iyset*16+izset*32 45259599516SKenneth E. Jansen BCtmp(nn,7)=zero 45359599516SKenneth E. Jansen BCtmp(nn,11)=zero 45459599516SKenneth E. Jansen wnrm(nn,:)=BCtmp(nn,4:6)+BCtmp(nn,8:10) 45559599516SKenneth E. Jansen else if(nsurf(nn).gt.2) then 45659599516SKenneth E. Jansenc If this node is shared by more than two modeled walls, then 45759599516SKenneth E. Jansenc it is a corner node and it will be treated as having no slip 45859599516SKenneth E. Jansenc The normals for all surfaces beyond the first two were 45959599516SKenneth E. Jansenc contributed to the first vector of BCtmp 46059599516SKenneth E. Jansen wnrm(nn,:)=BCtmp(nn,4:6)+BCtmp(nn,8:10) 46159599516SKenneth E. Jansen iBC(nn)=iBC(nn)+56 46259599516SKenneth E. Jansen BCtmp(nn,7)=zero 46359599516SKenneth E. Jansen endif ! curved surface 46459599516SKenneth E. Jansen else if(abs(itwmod).eq.2) then ! effective viscosity wall-model 46559599516SKenneth E. Jansenc Otherwise, we're using the effective-viscosity wall-model and the 46659599516SKenneth E. Jansenc nodes on modeled surfaces are treated as no-slip 46759599516SKenneth E. Jansen iBC(nn)=iBC(nn)+56 ! set 3-comp 46859599516SKenneth E. Jansen if(itwmod.eq.-2) BCtmp(nn,7)=zero ! no slip 46959599516SKenneth E. Jansen if(nsurf(nn).eq.1) 47059599516SKenneth E. Jansen & wnrm(nn,:)=BCtmp(nn,4:6) 47159599516SKenneth E. Jansen if(nsurf(nn).ge.2) 47259599516SKenneth E. Jansen & wnrm(nn,:)=BCtmp(nn,4:6)+BCtmp(nn,8:10) 47359599516SKenneth E. Jansen endif 47459599516SKenneth E. Jansenc Now normalize the wall normal for this node 47559599516SKenneth E. Jansen if(itwmod.ne.0) then 47659599516SKenneth E. Jansen wmag=sqrt(wnrm(nn,1)*wnrm(nn,1) 47759599516SKenneth E. Jansen & +wnrm(nn,2)*wnrm(nn,2)+wnrm(nn,3)*wnrm(nn,3)) 47859599516SKenneth E. Jansen wnrm(nn,:)=wnrm(nn,:)/wmag 47959599516SKenneth E. Jansen endif 48059599516SKenneth E. Jansenc 48159599516SKenneth E. Jansenc.... put back the comp3 info for bctmp 48259599516SKenneth E. Jansenc 48359599516SKenneth E. Jansen if(ikp.eq.1) then 48459599516SKenneth E. Jansen iBC(nn)=iBCSAV+56 ! put it back to a comp3 48559599516SKenneth E. Jansen BCtmp(nn,:)=BCtmpSAV(nn,:) ! ditto 48659599516SKenneth E. Jansen endif 48759599516SKenneth E. Jansen enddo ! loop over all nodes 48859599516SKenneth E. Jansen endif ! end "if there are any surfID's" 48959599516SKenneth E. Jansenc 49059599516SKenneth E. Jansenc If you are using the turbulence wall with axisymmetry you 49159599516SKenneth E. Jansenc need to modify the axisymmetry angle to account for the discrete 49259599516SKenneth E. Jansenc normals at the wall being different than the exact normals 49359599516SKenneth E. Jansenc 49459599516SKenneth E. Jansenc find the my normal, my partners normal and correct the angle 49559599516SKenneth E. Jansenc$$$ 49659599516SKenneth E. Jansenc$$$ do i=1,numnp 49759599516SKenneth E. Jansenc$$$ wmag = wnrm(i,1) * wnrm(i,1) 49859599516SKenneth E. Jansenc$$$ & + wnrm(i,2) * wnrm(i,2) 49959599516SKenneth E. Jansenc$$$ & + wnrm(i,3) * wnrm(i,3) 50059599516SKenneth E. Jansenc$$$c 50159599516SKenneth E. Jansenc$$$c only "fix" wall nodes...other nodes still have a zero in wnrm 50259599516SKenneth E. Jansenc$$$c 50359599516SKenneth E. Jansenc$$$ if((btest(iBC(i),12)).and.(wmag.ne.zero)) then 50459599516SKenneth E. Jansenc$$$ BCtmp(i,1)=acos( wnrm(i,1) * wnrm(iper(i),1) 50559599516SKenneth E. Jansenc$$$ & + wnrm(i,2) * wnrm(iper(i),2) 50659599516SKenneth E. Jansenc$$$ & + wnrm(i,3) * wnrm(iper(i),3) ) 50759599516SKenneth E. Jansenc$$$ endif 50859599516SKenneth E. Jansenc$$$ enddo 50959599516SKenneth E. Jansenc 51059599516SKenneth E. Jansenc.... return 51159599516SKenneth E. Jansenc 51259599516SKenneth E. Jansen return 51359599516SKenneth E. Jansenc 51459599516SKenneth E. Jansen end 51559599516SKenneth E. Jansen 51659599516SKenneth E. Jansen 51759599516SKenneth E. Jansen subroutine gensidcount(nsidg) 51859599516SKenneth E. Jansenc--------------------------------------------------------------------- 51959599516SKenneth E. Jansenc 52059599516SKenneth E. Jansenc This routine counts up the total number of surface ID's across 52159599516SKenneth E. Jansenc all processors and makes a list of them 52259599516SKenneth E. Jansenc 52359599516SKenneth E. Jansenc Inputs: 52459599516SKenneth E. Jansenc iBCB natural boundary condition switches and surfIDs 52559599516SKenneth E. Jansenc 52659599516SKenneth E. Jansenc Outputs: 52759599516SKenneth E. Jansenc nsidg number of surface ID's globally (including all procs) 52859599516SKenneth E. Jansenc sidmapg global list of surface ID's, lowest to highest 52959599516SKenneth E. Jansenc 53059599516SKenneth E. Jansenc--------------------------------------------------------------------- 53159599516SKenneth E. Jansen use pointer_data ! access to miBCB 53259599516SKenneth E. Jansen use turbSA ! access to sidmapg 53359599516SKenneth E. Jansen include "common.h" 53459599516SKenneth E. Jansen include "mpif.h" 53559599516SKenneth E. Jansenc 53659599516SKenneth E. Jansen integer newflag, i, j 53759599516SKenneth E. Jansen integer nsidl ! number of surface IDs on-proc 53859599516SKenneth E. Jansen integer nsidt ! sum of all nsidl's 53959599516SKenneth E. Jansen integer nsidg ! number of surface IDs globally 54059599516SKenneth E. Jansen integer nsid(numpe) ! array of nsidl's 54159599516SKenneth E. Jansen integer idisp(numpe) ! needed by mpi: see note below 54259599516SKenneth E. Jansen type llnod ! structure for one node in a linked list 54359599516SKenneth E. Jansen integer :: value 54459599516SKenneth E. Jansen type (llnod), pointer :: next 54559599516SKenneth E. Jansen end type llnod 54659599516SKenneth E. Jansen type (llnod), pointer :: sidlist ! points to first elt of linked list 54759599516SKenneth E. Jansen type (llnod), pointer :: sidelt ! points to generic elt of linked list 5486f04c980SCameron Smith type (llnod), pointer :: nextelt ! points to generic elt of linked list 54959599516SKenneth E. Jansen integer, allocatable :: sidmapl(:) ! list of surfID's on-proc 55059599516SKenneth E. Jansen integer, allocatable :: temp(:) ! temp space 55159599516SKenneth E. Jansenc integer iBCB(numelb,ndiBCB) ! column 1: naturalBC switches 55259599516SKenneth E. Jansen ! column 2: surface ID's 55359599516SKenneth E. Jansenc Since we don't know a priori how many surface ID's there are, 55459599516SKenneth E. Jansenc on-processor or globally, we will store the ID's as an open-ended 55559599516SKenneth E. Jansenc link list while we determine the total number of distinct ID's 55659599516SKenneth E. Jansen allocate (sidlist) ! allocate the first element of the sid 55759599516SKenneth E. Jansen ! linked list and point sidlist to it 55859599516SKenneth E. Jansen nsidl=0 ! initialize # of sids on this processor 55959599516SKenneth E. Jansen nsidg=0 5606f04c980SCameron Smith nullify(sidlist % next) ! next does not exist yet 56159599516SKenneth E. Jansen do iblk=1, nelblb ! loop over boundary element blocks 56259599516SKenneth E. Jansen npro = lcblkb(1,iblk+1)-lcblkb(1,iblk) 56359599516SKenneth E. Jansen do i = 1, npro ! loop over boundary elements (belts) 56459599516SKenneth E. Jansen iBCB2=miBCB(iblk)%p(i,2) 56559599516SKenneth E. Jansen if(iBCB2.ne.zero) then ! if a sid is given for this belt 56659599516SKenneth E. Jansen if(nsidl.eq.0) then ! if this is the first sid we've seen 56759599516SKenneth E. Jansen nsidl=1 ! increment our count and 56859599516SKenneth E. Jansen sidlist % value = iBCB2 ! record its value 5696f04c980SCameron Smith nullify(sidlist % next) ! next does not exist yet 57059599516SKenneth E. Jansen else ! if this isn't the first sid 57159599516SKenneth E. Jansen newflag = 1 ! assume this is a new sid 57259599516SKenneth E. Jansen sidelt => sidlist ! starting with the first sid 57359599516SKenneth E. Jansen do j = 1, nsidl ! check the assumption 57459599516SKenneth E. Jansen if((sidelt % value).eq.iBCB2) then 57559599516SKenneth E. Jansen newflag=0 ! ... 57659599516SKenneth E. Jansen endif 57759599516SKenneth E. Jansen if(j.ne.nsidl) then ! ... 57859599516SKenneth E. Jansen sidelt => sidelt % next 57959599516SKenneth E. Jansen endif! ... 58059599516SKenneth E. Jansen enddo 58159599516SKenneth E. Jansen if(newflag.eq.1) then! if it really is new to us 58259599516SKenneth E. Jansen nsidl = nsidl + 1 ! increment our count 58359599516SKenneth E. Jansen allocate (sidelt % next)! tack a new element to the end 58459599516SKenneth E. Jansen sidelt => sidelt % next! point to the new element 58559599516SKenneth E. Jansen sidelt % value = iBCB2 ! record the new sid 5866f04c980SCameron Smith nullify(sidelt % next) ! next does not exist yet 58759599516SKenneth E. Jansen endif ! (really is a new sid) 58859599516SKenneth E. Jansen endif ! (first sid) 58959599516SKenneth E. Jansen endif ! (belt has a sid) 59059599516SKenneth E. Jansen enddo ! (loop over belts) 59159599516SKenneth E. Jansen enddo ! (loop over boundary element blocks) 59259599516SKenneth E. Jansenc Copy the data from the linked list to a more easily-used array form 59359599516SKenneth E. Jansen if(nsidl.gt.0) then 59459599516SKenneth E. Jansen allocate( sidmapl(nsidl) ) 59559599516SKenneth E. Jansen sidelt => sidlist ! starting with the first sid 59659599516SKenneth E. Jansen do j = 1, nsidl 59759599516SKenneth E. Jansen sidmapl(j)=sidelt%value 59859599516SKenneth E. Jansen if(j.ne.nsidl) sidelt => sidelt%next 59959599516SKenneth E. Jansen enddo 60059599516SKenneth E. Jansen else 60159599516SKenneth E. Jansen allocate( sidmapl(1)) ! some compilers/MPI don't like to send unallocated arrays 60259599516SKenneth E. Jansen endif 6036f04c980SCameron Smith! Deallocate the link list 6046f04c980SCameron Smith! http://stackoverflow.com/questions/9184675/how-does-fortran-deallocate-linked-lists 6056f04c980SCameron Smith sidelt => sidlist 6066f04c980SCameron Smith nextelt => sidelt % next 6076f04c980SCameron Smith do 6086f04c980SCameron Smith deallocate(sidelt) 6096f04c980SCameron Smith if( .not. associated(nextelt) ) exit 6106f04c980SCameron Smith sidelt => nextelt 6116f04c980SCameron Smith nextelt => sidelt % next 6126f04c980SCameron Smith enddo 6136f04c980SCameron Smith 61459599516SKenneth E. Jansenc Gather the number of surface ID's on each processor 61559599516SKenneth E. Jansen if (numpe.gt.1) then ! multiple processors 61659599516SKenneth E. Jansenc write the number of surfID's on the jth processor to slot j of nsid 61759599516SKenneth E. Jansen call MPI_ALLGATHER(nsidl,1,MPI_INTEGER,nsid,1, 61859599516SKenneth E. Jansen & MPI_INTEGER,MPI_COMM_WORLD,ierr) 61959599516SKenneth E. Jansenc count up the total number of surfID's among all processes 62059599516SKenneth E. Jansen nsidt=0 62159599516SKenneth E. Jansen do j=1,numpe 62259599516SKenneth E. Jansen nsidt=nsidt+nsid(j) 62359599516SKenneth E. Jansen enddo 62459599516SKenneth E. Jansen else ! single processor 62559599516SKenneth E. Jansenc the local information is the global information for single-processor 62659599516SKenneth E. Jansen nsid=nsidl 62759599516SKenneth E. Jansen nsidt=nsidl 62859599516SKenneth E. Jansen endif ! if-else for multiple processors 62959599516SKenneth E. Jansen if(nsidt.gt.0) then 63059599516SKenneth E. Jansenc 63159599516SKenneth E. Jansenc Make all-processor surfID collage 63259599516SKenneth E. Jansenc 63359599516SKenneth E. Jansenc there will be some duplicate surface ID's when we gather, so we 63459599516SKenneth E. Jansenc will use a temporary array 63559599516SKenneth E. Jansen allocate (temp(nsidt)) 63659599516SKenneth E. Jansen if (numpe.gt.1) then ! multiple processors 63759599516SKenneth E. Jansenc we will gather surfID's from local on-proc sets to a global set 63859599516SKenneth E. Jansenc we will stack each processor's surfID list atop that of the previous 63959599516SKenneth E. Jansenc processor. If the list for processor i is called sidmapi, then our 64059599516SKenneth E. Jansenc global coordinate list sidmap will look like this: 64159599516SKenneth E. Jansenc --------------------------------------------------------------- 64259599516SKenneth E. Jansenc | sidmap1 | sidmap2 | sidmap3 | ... | 64359599516SKenneth E. Jansenc --------------------------------------------------------------- 64459599516SKenneth E. Jansenc <---nsid(1)---> <-----nsid(2)-----> <-nsid(3)-> 64559599516SKenneth E. Jansenc <------------------------nsidt-----------------------...----> 64659599516SKenneth E. Jansenc To accomplish this with MPI, we use MPI_ALLGATHERV, summarized as: 64759599516SKenneth E. JansencMPI_ALLGATHERV(sendbuf,sendcount,sendtype,recvbuf,recvcount,disp,recvtype,comm) 64859599516SKenneth E. Jansenc[ IN sendbuf] starting address of send buffer (choice) 64959599516SKenneth E. Jansenc[ IN sendcount] number of elements in send buffer (integer) 65059599516SKenneth E. Jansenc[ IN sendtype] data type of send buffer elements (handle) 65159599516SKenneth E. Jansenc[ OUT recvbuf] address of receive buffer (choice) 65259599516SKenneth E. Jansenc[ IN recvcount] number of elements received from each process (int array) 65359599516SKenneth E. Jansenc[ IN disp] displacement array 65459599516SKenneth E. Jansenc[ IN recvtype] data type of receive buffer elements (handle) 65559599516SKenneth E. Jansenc[ IN comm] communicator (handle) 65659599516SKenneth E. Jansenc The displacement array disp is an array of integers in which the jth 65759599516SKenneth E. Jansenc entry indicates which slot of sidmap marks beginning of sidmapj 65859599516SKenneth E. Jansenc So, first we will build this displacement array 65959599516SKenneth E. Jansen idisp(:)=0 ! starting with zero, since MPI likes C-numbering 66059599516SKenneth E. Jansen do j=2,numpe 66159599516SKenneth E. Jansen idisp(j)=idisp(j-1)+nsid(j-1) ! see diagram above 66259599516SKenneth E. Jansen enddo 66359599516SKenneth E. Jansenc Now, we gather the data 66459599516SKenneth E. Jansen call MPI_ALLGATHERV(sidmapl(:),nsidl, 66559599516SKenneth E. Jansen & MPI_INTEGER,temp(:),nsid,idisp, 66659599516SKenneth E. Jansen & MPI_INTEGER,MPI_COMM_WORLD,ierr) 66759599516SKenneth E. Jansenc sort surfID's, lowest to highest 66859599516SKenneth E. Jansen isorted = 0 66959599516SKenneth E. Jansen do while (isorted.eq.0) ! while the list isn't sorted 67059599516SKenneth E. Jansen isorted = 1 ! assume the list is sorted this time 67159599516SKenneth E. Jansen do j = 2, nsidt ! loop over ID's 67259599516SKenneth E. Jansen if(temp(j).lt.temp(j-1)) then ! ID exceeds predecessor 67359599516SKenneth E. Jansen itmp=temp(j-1) 67459599516SKenneth E. Jansen temp(j-1)=temp(j) 67559599516SKenneth E. Jansen temp(j)=itmp 67659599516SKenneth E. Jansen isorted=0 ! not sorted yet 67759599516SKenneth E. Jansen endif 67859599516SKenneth E. Jansen enddo !loop over ID's 67959599516SKenneth E. Jansen enddo ! while not sorted 68059599516SKenneth E. Jansenc determine the total number of distinct surfID's, globally 68159599516SKenneth E. Jansen nsidg=nsidt ! assume there are no duplicate SurfID's 68259599516SKenneth E. Jansen do j = 2, nsidt 68359599516SKenneth E. Jansen if(temp(j).eq.temp(j-1)) nsidg = nsidg - 1 ! correction 68459599516SKenneth E. Jansen enddo 68559599516SKenneth E. Jansenc create duplicate-free surfID list 68659599516SKenneth E. Jansen allocate( sidmapg(nsidg) ) 68759599516SKenneth E. Jansen sidmapg(1)=temp(1) 68859599516SKenneth E. Jansen nsidg = 1 68959599516SKenneth E. Jansen do j = 2, nsidt 69059599516SKenneth E. Jansen if(temp(j).ne.temp(j-1)) then 69159599516SKenneth E. Jansen nsidg = nsidg + 1 69259599516SKenneth E. Jansen sidmapg(nsidg)=temp(j) 69359599516SKenneth E. Jansen endif 69459599516SKenneth E. Jansen enddo 69559599516SKenneth E. Jansen deallocate( temp ) 69659599516SKenneth E. Jansen else ! single-processor 69759599516SKenneth E. Jansenc global data is local data in single processor case 69859599516SKenneth E. Jansen nsidg=nsidl 69959599516SKenneth E. Jansen allocate( sidmapg(nsidg) ) 70059599516SKenneth E. Jansen sidmapg=sidmapl 7016f04c980SCameron Smith deallocate(sidmapl) 70259599516SKenneth E. Jansen endif ! if-else multiple processor 70359599516SKenneth E. Jansenc 70459599516SKenneth E. Jansen endif ! if at least one surfid 70559599516SKenneth E. Jansenc 70659599516SKenneth E. Jansen return 70759599516SKenneth E. Jansenc 70859599516SKenneth E. Jansen end 70959599516SKenneth E. Jansen 71059599516SKenneth E. Jansen 71159599516SKenneth E. Jansen 71259599516SKenneth E. Jansen subroutine genotwn(x, BCtmp, iBC, nsurf) 71359599516SKenneth E. Jansenc 71459599516SKenneth E. Jansenc---------------------------------------------------------------------- 71559599516SKenneth E. Jansenc This routine determines which node to use as the first node off the 71659599516SKenneth E. Jansenc wall in near-wall modeling traction calculations for each wall node. 71759599516SKenneth E. Jansenc Each wall node has a normal, calculated from the wall elements to 71859599516SKenneth E. Jansenc which that node belongs. We seek the node within the boundary 71959599516SKenneth E. Jansenc element that lies closest to the line defined by the normal vector. 72059599516SKenneth E. Jansenc We create normalized vectors pointing from the wall node in 72159599516SKenneth E. Jansenc question to each of the nodes in the boundary element. The vector 72259599516SKenneth E. Jansenc that has the largest projection onto the wall node's normal vector 72359599516SKenneth E. Jansenc points to the node we want. Nodes that are not on a wall point to 72459599516SKenneth E. Jansenc themselves as their own off-the-wall node. 72559599516SKenneth E. Jansenc 72659599516SKenneth E. Jansenc input: 72759599516SKenneth E. Jansenc x (nshg,3) : : nodal position vectors 72859599516SKenneth E. Jansenc wnrm (nshg,3) : (mod) : normal vectors for each node 72959599516SKenneth E. Jansenc iBCB5 (nshg) : (file) : wall flag for belt 73059599516SKenneth E. Jansenc ienb (numelb,nen) : (file) : connectivity for belts 73159599516SKenneth E. Jansenc 73259599516SKenneth E. Jansenc output: 73359599516SKenneth E. Jansenc otwn (nshg) : (mod) : off-the-wall nodes for each node 73459599516SKenneth E. Jansenc 73559599516SKenneth E. Jansenc 73659599516SKenneth E. Jansenc Kenneth Jansen, Summer 2000 (algorithm) 73759599516SKenneth E. Jansenc Michael Yaworski, Summer 2000 (code) 73859599516SKenneth E. Jansenc---------------------------------------------------------------------- 73959599516SKenneth E. Jansenc 74059599516SKenneth E. Jansen use pointer_data ! used for mienb, miBCB 74159599516SKenneth E. Jansen use turbSA 74259599516SKenneth E. Jansen include "common.h" 74359599516SKenneth E. Jansenc 74459599516SKenneth E. Jansen integer iel, nod, can 74559599516SKenneth E. Jansen real*8 vec(3), leng, dp, bigdp, lil 74659599516SKenneth E. Jansen real*8 x(numnp,nsd),BCtmp(nshg,ndof+7) 74759599516SKenneth E. Jansen integer iBC(nshg), nsurf(nshg) 74859599516SKenneth E. Jansen integer gbits 74959599516SKenneth E. Jansen integer, allocatable :: ienb(:) 75059599516SKenneth E. Jansen 75159599516SKenneth E. Jansen allocate( otwn(nshg) ) 75259599516SKenneth E. Jansenc 75359599516SKenneth E. Jansenc initialize otwn to oneself 75459599516SKenneth E. Jansenc 75559599516SKenneth E. Jansen do nod = 1, nshg 75659599516SKenneth E. Jansen otwn(nod)=nod 75759599516SKenneth E. Jansen enddo 75859599516SKenneth E. Jansenc 75959599516SKenneth E. Jansenc determine otwn for each wall node 76059599516SKenneth E. Jansenc 76159599516SKenneth E. Jansen do iblk=1, nelblb ! loop over boundary element blocks 76259599516SKenneth E. Jansen npro = lcblkb(1,iblk+1)-lcblkb(1,iblk) 76359599516SKenneth E. Jansen nenl = lcblkb(5,iblk) 76459599516SKenneth E. Jansen nenbl = lcblkb(6,iblk) 76559599516SKenneth E. Jansen nshl = lcblkb(9,iblk) 76659599516SKenneth E. Jansen allocate( ienb(nshl) ) 76759599516SKenneth E. Jansen do i = 1, npro ! loop over boundary elements 76859599516SKenneth E. Jansen iBCB1=miBCB(iblk)%p(i,1) 76959599516SKenneth E. Jansen iBCB2=miBCB(iblk)%p(i,2) 77059599516SKenneth E. Jansen ienb(1:nshl)=mienb(iblk)%p(i,1:nshl) 77159599516SKenneth E. Jansen if (btest(iBCB1,4)) then ! (on the wall) 77259599516SKenneth E. Jansen do nod = 1, nenbl ! for each wall node in this belt 77359599516SKenneth E. Jansen bigdp = zero ! initialize largest dot product 77459599516SKenneth E. Jansen do can=nenbl+1,nenl ! loop over off-the-wall candidates 77559599516SKenneth E. Jansen nn=ienb(can) 77659599516SKenneth E. Jansen ! don't bother with wall nodes 77759599516SKenneth E. Jansen if(nsurf(nn).ne.0) cycle 77859599516SKenneth E. Jansen ! don't bother with no-slip nodes 77959599516SKenneth E. Jansen if(ibits(iBC(nn),3,3).eq.7 .and. 78059599516SKenneth E. Jansen & BCtmp(nn,7).eq.zero) cycle 78159599516SKenneth E. Jansenc ! calculate candidate vector 78259599516SKenneth E. Jansen vec(:)=x(ienb(can),:)-x(ienb(nod),:) 78359599516SKenneth E. Jansen leng=sqrt(vec(1)**2+vec(2)**2+vec(3)**2) 78459599516SKenneth E. Jansen vec(:)=vec(:)/leng 78559599516SKenneth E. Jansenc ! calculate dot product with wnrm 78659599516SKenneth E. Jansen vec(:)=vec(:)*wnrm(ienb(nod),:) 78759599516SKenneth E. Jansen dp=vec(1)+vec(2)+vec(3) 78859599516SKenneth E. Jansenc ! set candidate as otwn if necessary 78959599516SKenneth E. Jansenc ! (wnrm points into fluid, so 79059599516SKenneth E. Jansenc ! we want the most positive dp) 79159599516SKenneth E. Jansen if (dp.gt.bigdp) then 79259599516SKenneth E. Jansen otwn(ienb(nod)) = ienb(can) 79359599516SKenneth E. Jansen bigdp=dp 79459599516SKenneth E. Jansen endif 79559599516SKenneth E. Jansen enddo !(loop over off-the-wall candidates) 79659599516SKenneth E. Jansen enddo !(loop over wall nodes in current belt) 79759599516SKenneth E. Jansen endif 79859599516SKenneth E. Jansen enddo !(loop over elts in block) 79959599516SKenneth E. Jansen deallocate(ienb) 80059599516SKenneth E. Jansen enddo !(loop over boundary element blocks) 80159599516SKenneth E. Jansen do nn = 1, nshg 80259599516SKenneth E. Jansen if((otwn(nn).eq.nn).and.(nsurf(nn).ne.0)) then ! if a node on a 80359599516SKenneth E. Jansen ! modeled surface 80459599516SKenneth E. Jansen ! didn't find a node 80559599516SKenneth E. Jansen ! off the wall 80659599516SKenneth E. Jansen lil = 1.0e32 ! distance to current closest prospect 80759599516SKenneth E. Jansen do can = 1, nshg ! loop over nodes 80859599516SKenneth E. Jansen if(nsurf(can).eq.0) then ! if this candidate is off the 80959599516SKenneth E. Jansen ! wall 81059599516SKenneth E. Jansen if(ibits(iBC(can),3,3).eq.7 .and. 81159599516SKenneth E. Jansen & BCtmp(can,7).eq.zero) then ! no slip nodes not allowed 81259599516SKenneth E. Jansen else ! not a forbidden node 81359599516SKenneth E. Jansen vec(:)=x(nn,:)-x(can,:) 81459599516SKenneth E. Jansen leng=vec(1)**2+vec(2)**2+vec(3)**2 81559599516SKenneth E. Jansen if(leng.lt.lil) then ! this candidate is closest so far 81659599516SKenneth E. Jansen lil=leng 81759599516SKenneth E. Jansen otwn(nn)=can 81859599516SKenneth E. Jansen endif ! closest so far 81959599516SKenneth E. Jansen endif ! end of no slip nodes 82059599516SKenneth E. Jansen endif ! off-the-wall check 82159599516SKenneth E. Jansen enddo ! loop over nodes 82259599516SKenneth E. Jansen endif ! lonely wall-node check 82359599516SKenneth E. Jansen enddo ! loop over nodes 82459599516SKenneth E. Jansenc 82559599516SKenneth E. Jansen return 82659599516SKenneth E. Jansenc 82759599516SKenneth E. Jansen end 82859599516SKenneth E. Jansen 829