[boundary] Half-way boundary


What modifications of the code is required to implement half-way boundary? I know that I should call getNx(true), getNy(true) and getNz(true). But how should I modify the rest of the code for example:

boundaryCondition = createInterpBoundaryCondition2D(lattice);
// boundaryCondition = createLocalBoundaryCondition2D(lattice);

Best regards,


I’m not completely sure I understand exactly what you mean. Do you want to use half-way bounce-back, or just use normal bounce-back and have the boundaries located halfway from the wall site?

If you want the halfway bounce back, then you should do anything. You just do not add any boundary condition on the wall site.
And it should work fine. Do not use collideAndStream(true) method, the periodic BC would “kill” the halfway bounceback BC. This nice feature is due to the “swap” trick for the streaming.

I hope it answered your question. If not then just explain a bit better what you want to do and i’ll try to give a better answer.


When you switch from an on-lattice boundary condition, such as Zou/He, to a half-way-between-lattice boundary condition, such as full-way bounce-back (see http://www.lbmethod.org/models:bc for more information), you need to be careful as to how to relate lattice indices to physical coordinates.

Consider, for the sake of illustration, a channel with a resolution of 2 grid cells from one wall to another. Using an on-lattice boundary condition, this requires three grid nodes, as shown on the following sketch:


The lines | label the nodes on which the boundary condition is implemented, and which correspond to the physical location of the boundary. There is an additional bulk node * between the two. If you call x the physical coordinate ranging from 0 to 1 between the two walls, you find the following relation between the lattice index iX and the physical location:

x = iX * 1/N

Here, N=2 is the lattice resolution.

With full-way bounce-back, four grid nodes are needed, as shown on the following sketch:


The four grid nodes are labelled by a star *, and full-way bounce-back is implemented on node 0 and on node 3. The physical wall location is indicated by a line | . Here, the relation between lattice index and physical location is

x = (iX-1/2) * 1/N

The OpenLB class LBunits does only part of the job for you: computing the total number of grid nodes. This is, if you instantiate a LBunits object with resolution N=2 and geometry lx=1, the method getNx(), or getNx(false) stands for on-lattice and yields 3, whereas the method call getNx(true) stands for half-way-between-nodes and yields 4.

You need however to take into account yourself the shift factor 1/2 in the bounce-back case, for example when initializing the boundary condition, or cross-checking the numerical result with an analytical profile. In practice, this probably amounts to something like calling computePoiseuilleProfile(iX-0.5) instead of computePoiseuilleProfile(iX) (and making sure that the parameter of computePoiseuilleProfile is real-valued instead of integer-valued).

By the way, if your question is about how to implement full-way bounce-back in OpenLB, you should have a look at the example cylinder2d. Because of the simplicity of this boundary condition, the formalism of the “OnLatticeBoundaryCondition” class is not required in this case: full-way bounce-back dynamics can directly be assigned to lattice nodes, in a single command.

Many thanks for your detailed answer.

(a) To apply “half”-way bounce back with boundary located half-way from boundary site:
(1) I need to use collideAndStream(false).
(2) use getNx(true).
(3) adjust iX -> iX-1/2 (according to your second message).

(Q1) What if the domain contains part where periodic boundary is required and other part where the above boundary is required? I can not use collideAndStream(false). How will I apply periodic b.c. at that case?

(b) To apply “full”-way bounce back with boundary located half-way from boundary site:
(1) I select the nodes by if statement as in cylinder2d and use lattice.defineDynamics(…).
(2) use getNx(true).
(3) adjust iX -> iX-1/2 (according to your second message).

(Q2) in your second message you said:

[quote=when initializing the boundary condition, or …][/quote]
what did you mean by that? Thanks.

Best regards,


[quote=(Q1)… I can not use collideAndStream(TRUE). How will I apply periodic b.c. at that case?][/quote]

As far as full-way bounce-back is concerned, your understanding of the algorithm seems to be OK. About initializing the boundary condition: if you implement a cavity flow, forget what I said. If however you implement a flow in which the boundary has a velocity profile depending on position (for example Poiseuille flow), then you need to be aware to interpret the coordinates properly when computing this profile.

For half-way bounce-back, there is no easy way to combine periodic boundaries with half-way bounce-back boundaries. If you really want to do this, you need to implement half-way separately through a new dynamics, like full-way. Also, I don’t think that your interpretation of the index in the half-way bounce-back case is correct. Unlike full-way bounce-back, where the boundary is between the bounce-back node and the next fluid node, I think that in the half-way bounce-back case it is located in the other direction, between the bounce-back node and the next exterior node. But Orestis should maybe comment on this, he is the expert.

Jonas is indeed correct. When using half way bounce back, you should be careful because in order to achieve second order accuracy you should place the wall at the exterior of your computational domain at a distance of 1/2.


where “x” a the last bulk node, “o” the halfway bounce back node, and “|” the position of the wall. This is different from the full way bounce back, where


I hope this clarifies a bit things.


1 Like