KTH framework for Nek5000 toolboxes; testing version  0.0.1
lb_setqvol.f
Go to the documentation of this file.
1 c-----------------------------------------------------------------------
2  subroutine lb_setqvol(flocal,qvol,in,m,isInactive)
3 c
4 c Compute user specified volumetric source term vector using
5 c flocal(real inout(m),m) for all 'active' (isInactive==0)
6 c fluid points
7 c
8  include 'SIZE'
9 c
10  real qvol(lx1,ly1,lz1,lelv,*),in(lx1,ly1,lz1,lelt,*)
11  integer isInactive(lx1,ly1,lz1,*)
12 
13  integer lb_imap(lx1*ly1*lz1*lelv)
14  common /lbr/ buf(ldimt,lx1*ly1*lz1*lelv)
15  real buf
16 
17  external flocal
18 
19  lqvol = lx1*ly1*lz1*lelv
20  lin = lx1*ly1*lz1*lelt
21  ntot = lx1*ly1*lz1*nelv
22 
23  ! pack input data
24  n = 0
25  do i = 1,ntot
26  if(isinactive(i,1,1,1).eq.0) then
27  n = n + 1
28  lb_imap(n) = i
29  do j = 1,m
30  k = (j-1)*lin + i
31  buf(j,n) = in(k,1,1,1,1)
32  enddo
33  endif
34  enddo
35 
36  ! distribute input data ->compute output data ->transfer back
37  nmax = lin
38  call lb_process_items(n,buf,flocal,m,nmax)
39 
40  ! unpack output data
41  do i = 1,n
42  do k = 1,m
43  j = (k-1)*lqvol + lb_imap(i)
44  qvol(j,1,1,1,1) = buf(k,i)
45  enddo
46  enddo
47 
48  return
49  end
50 c-----------------------------------------------------------------------
51  subroutine lb_process_items(nin,rdata,flocal,m,nmax)
52 c
53  include 'SIZE'
54  common /nekmpi/ nidd,npp,nekcomm,nekgroup,nekreal
55 
56  real rdata(1)
57  external flocal
58 
59  integer*8 i8gl_running_sum, i8rsum
60  integer*8 n8, np8, nb8
61 
62  common /scrns/ vi(2,lx1*ly1*lz1*lelt)
63  integer vi
64 
65  integer icalld,cr_lb
66  data icalld /0/
67  save icalld,cr_lb
68 
69  parameter(kid = 1) ! column to store local id
70  parameter(kp = 2) ! column to store rank tag
71 
72  real tcomm
73  data tcomm /0.0/
74  save tcomm
75 
76  n = nin
77  n0 = n
78 
79  if(icalld.eq.0) then
80  call fgslib_crystal_setup(cr_lb,nekcomm,npp)
81  icalld = 1
82  endif
83 
84  ! partition into chunks
85  ! note: simple approach but not of approx. equal size
86  n8 = n
87  np8 = npp
88  ng8 = i8glsum(n8,1)
89  nb8 = ng8/np8
90  do i = 0,mod(ng8,np8)-1
91  if(nid.eq.i) nb8 = nb8 + 1
92  enddo
93  i8rsum = i8gl_running_sum(n8) - n8
94  do i=1,n
95  vi(kid,i) = i
96  ig = i8rsum + i
97  vi(kp ,i) = (ig-1)/nb8
98  enddo
99 
100  if (loglevel.gt.2) then
101  n0_max = iglmax(n0,1)
102  n0_min = iglmin(n0,1)
103  endif
104 
105  etime = dnekclock_sync()
106  call fgslib_crystal_tuple_transfer
107  & (cr_lb,n,nmax,vi,2,vl,0,rdata,m,kp)
108  tcomm = tcomm + dnekclock_sync() - etime
109 
110  if (loglevel.gt.2) then
111  n_max = iglmax(n,1)
112  n_min = iglmin(n,1)
113  endif
114 
115  do j = 1,n
116  jj = (j-1)*m + 1
117  call flocal(rdata(jj),m)
118  enddo
119 
120  etime = dnekclock_sync()
121  call fgslib_crystal_tuple_transfer
122  & (cr_lb,n,nmax,vi,2,vl,0,rdata,m,kp)
123  tcomm = tcomm + dnekclock_sync() - etime
124 
125  if (n.gt.nmax) call exitti('lb_process_items nmax too small$',n)
126  if (n.ne.n0) call exitti('lb_process_items unexpected n$',n)
127 
128  key = kid ! restore based on local id
129  call fgslib_crystal_tuple_sort
130  & (cr_lb,n,vi,2,vl,0,rdata,m,key,1)
131 
132  if (loglevel.gt.2 .and. nid.eq.0) then
133  write(6,*) 'lb before nmax/nmin:', n0_max, n0_min
134  write(6,*) 'lb after nmax/nmin:', n_max , n_min
135  write(6,*) 'lb tcomm :', tcomm
136  endif
137 
138  return
139  end
subroutine exitti(stringi, idata)
Definition: comm_mpi.f:535
real *8 function dnekclock_sync()
Definition: comm_mpi.f:401
subroutine lb_setqvol(flocal, qvol, in, m, isInactive)
Definition: lb_setqvol.f:3
subroutine lb_process_items(nin, rdata, flocal, m, nmax)
Definition: lb_setqvol.f:52
function iglmax(a, n)
Definition: math.f:913
integer *8 function i8glsum(a, n)
Definition: math.f:947
function iglmin(a, n)
Definition: math.f:900