Hi Filipe,
I assume you want to add surface integral term via userbc like this
flux = Fx * unx + Fy * uny + Fz * unz
This can be tricky because we pass the volumetric index (ix,iy,iz,iel) to userbc.
And, what you really want is the face index (ia,iface,iel)
Nek5000 typically maps from face index to the volume one
like this:
DO 2000 IE=1,NEL
DO 2000 IFACE=1,NFACES
IA=0
CALL FACIND (KX1,KX2,KY1,KY2,KZ1,KZ2,lx1,ly1,lz1,IFACE)
DO 200 IZ=KZ1,KZ2
DO 200 IY=KY1,KY2
DO 200 IX=KX1,KX2
IA = IA + 1
S(IX,IY,IZ,IE) = S(IX,IY,IZ,IE) +
$ HC*AREA(IA,1,IFACE,IE)/BM1(IX,IY,IZ,IE)
but the reverse mapping is rarely used (it's also not unique on edges and corners)
Two approaches to consider:
a). You could define dummy arrays for each face and assign values in userchk:
real my_flux(lx1,ly1,lz1,6,lelt)
common /my_fld/ my_flux
! set up my_flux
and then reference them in userbc
iel = gllel(ieg)
flux = my_flux(ix,iy,iz,iface,iel)
However, this requires 6 volume arrays, which is quite a waste as we only care of some surface point.
Face based array is required. Otherwise, edges will be double counted.
The is an exception: if the desired face doesn't intersect with other faces with Neumann BC.
b). Add surface integral to right hand side like userq
(Also see BCNEUSC in bdry.f in terms of how to select the faces)
What you eventually need is
q(ix,iy,iz,ie) = q(ix,iy,iz,ie)
$ + flux(ia,1,iface,ie) * conductivity * area(ia,1,iface,ie) / bm1(ix,iy,iz,ie)
You can then save 1 volume array, pre-compute it in userchk, and reference it in userq via a common block.
Note that, a) and b) are not identical:
a) computes the flux based on current solution and use it as Neumann BC for the next.
b) directly computes the needed surface integral at right hand side. Then, Nek will do extrapolation on the top of it.
I'd assume b) is more accurate but can sometimes be unstable depending on how dynamic the BC changes.
Hope this helps,
Yu-Hsiang
--