Few simple questions

My other topic grew too large already so I’ll start fresh here. Especially since I switched from dynamics to data processors.
Will number my questions to make it easier to answer.

  1. What’s the proper way to initialize the height of fluid? InitializeAtEquilibrium with rho parameter seems like initializing the density and I want the density throughout the whole lattice to be constant. Want to initialize and monitor the water level.

  2. I’m using OneCellIndexedFunctional2D. What’s the proper way to run it in each iteration between collision and streaming phase? Now I’m using lattice.collide(), applyIndexed(lattice, box, new Functional()), lattice.stream(). Is there a way to reach the same result with single function call? Avoid creating new instance in each loop?

  3. I can get dx and dt using parameters.getDeltaX() and parameters.getDeltaT(), where parameters are of type IncomprFlowParam. Can I (how) extract parameters from lattice (Multi)BlockLattice2D?

  4. Is there a way to permanently disable streaming between two columns? Or do I have to use stream with Box2D parameter defining the domain?

  1. As I define boundary condition using data processor, what’s the proper way to disable any bounce back that occurs? Right now, I’m running the processor after collision phase and then apply streaming, but judging by the results, some default boundary condition is applied to these cells anyway (I defined BounceBack dynamics at the top and bottom wall, but I can see the water being bounced back also at inlet and outlet).
  1. What do you mean by height of fluid. I guess that you implemented a shallow water equation or something similar. Otherwise you do not have any "height of watter " out of the box. If I am not mistaken in the shallow water equation the height of water is “equivalent” with the density in palabos. So initializing the density at the height you want is as simple as initializing the density.

  2. You can use BoxProcessingFunctional2D instead. And then use integrateProcessingFunctional. But be aware that the DataProcessors integrate to the lattice with integrateProcessingFunctional are executed after the collision and streaming steps. This does not seem to be what you want since your DataProcessor is executed after collision.

  3. You cannot extract dx and dt directly from the lattice since it contains no information about the “physical” parameters of your flow. But if you want to use these parameters in a DataProcessor you can just pass them as members of the DataProcessor and initialize them with the constructor.

  4. There is no way to disable stream . The only way to do it is as you mention to enable it only on certain parts of the domain.

  5. On the boundaries of the domain, if the periodicity is “off” then by default the distribution functions that are incoming into the domain are doing a “half-way” bounceback. If periodicity is “on” then the f_i are juste streamed periodically.

I hope it helps.

1 Like

Thank you. Got three more questions:

  1. What’s the relation between distribution functions and density? Density = InitialDensity + sum(f)? I always thought the sum of distribution functions is equal to density.

  2. Why are some distribution functions negative after collision phase. What does it mean?

  3. Is there a nice and easy way to convert ScalarField2D into raw data? Or do I have to iterate through the whole field?


The “populations” (cell[i]) stored in Palabos correspond to f_i - t_i, and not to f_i. This is done in order to improve numerical accuracy, as explained here: http://lbmethod.org/howtos:reduce_roundoff .

Thank you. I read this page over a month ago, don’t know how I forget it. Is it possible to access t_i from th cell in order to restore the f_i?

I know, I always forget it myself. From the point of view of the design this was probably not the best decision. But I have the secret hope that one day somebody actually wants to run simulations in single precision and takes advantage of it.

T fi = cell[iPop] + Descriptor<T>::t[iPop];

Thank you, it works very well.
But I have another problem (I hope the last one).
I have the canal simulation. What I want to do now is to impose some kind of external force to simulate a slanted ground.

I changed the descriptor to descriptors::ForcedD2Q9Descriptor and added setExternalVector(*(this->lattice), this->lattice->getBoundingBox(), Descriptor::ExternalField::forceBeginsAt, Array<T,2>(10., 0.9)); in the lattice initialization function.

But no matter what force I set (tried up to 1000.), I don’t see the water leaning. What should I do?

Yet another question:
What’s the domain parameter for BoxProcessingFunctional2D_LL? What should I pass as argument if I want to process last column of the first lattice and first column of the second lattice?