Implementing Surface-directed spinodal decomposition
OpenLB – Open Source Lattice Boltzmann Code › Forums › on OpenLB › General Topics › Implementing Surface-directed spinodal decomposition
- This topic has 12 replies, 4 voices, and was last updated 1 year, 9 months ago by FBukreev.
-
AuthorPosts
-
January 16, 2023 at 12:27 pm #7123syedParticipant
Hello developers, I am trying to set up forcedshanchen interaction between the solid boundary and one of my components in a two-component system. I have already written the Spinodal decomposition application and am now trying to induce wetting by a component at the bottom surface.
How can I implement this using the Shan-Chen interaction potential?January 17, 2023 at 9:03 am #7124syedParticipantI am just thinking of how to couple ForcedShanchen dynamics between fluid and the boundary (different material numbers). I did it for fluid(A)-fluid(B). I want interaction potential between fluid and the boundary of the form = = G*Ψ(x)*s(x + e)e, where s is 1 if (x+e) is a wall boundary node and 0 otherwise.
January 18, 2023 at 10:12 am #7125mathiasKeymasterUsually you just set a particular density for both lattices seperatly but also your idea could be realised in a e.g. new postProcessor.
January 19, 2023 at 10:52 am #7126syedParticipantThank you Mathias for your reply. I see that I have to write a post-processor which will be integrated after the streaming process. Do I have to write it from scratch or do we have any such post-processor where I can just manipulate or insert the above-mentioned coupling?
January 19, 2023 at 2:41 pm #7127mathiasKeymasterI would copy-paste, rename and edit an existing one..
January 20, 2023 at 2:07 pm #7129syedParticipantI can find the one to edit, but can you suggest which one will be better? This will make my task more manageable. Thanking you in advance.
February 5, 2023 at 11:47 am #7170syedParticipantDear developers,
I am trying to write the post-processor for the boundary where I wanted to couple the ghost nodes with the nearest fluid with a pseudopotential of F=g(x)Ψ(x)s(x + e)e, where e is the discrete velocity and s(x+e) is 1 if x+e lies on the wall and 0 otherwise. I will substitute a constant for g(x).
So, my plan to implement this boundary is to write a post-processor, just like setFreeEnergyWall. Am I correct? Is this way to add the force F to my lattice points near the wall, and will this force be added to the collision term?
My work plan is as such:
1. Create Descriptor that holds additional fields (external F, velocity, Omega)
2. Prepare geometry (two Slatttices with 1 as fluid and 2 & 3 boundary material)
3. Patching dynamics to the fluid of Slattices (ForcedShanChen)
4. Creating coupling between Slattices (ShanChen pseudopotential)
5. Patching dynamics to boundaries (Upper wall only bounce-back)
6. Patching dynamics to boundaries (Lower wall bounce-back + Force described above)
7. Initialize lattice points with values
8. Collide&Stream
9. communication inter-Slattices
9. Execute coupling of point 4.Am I correct about the concepts? Adding postprocessor for wall and fluid nodes will add the F values to its dynamics and will be taken care in collide & stream?
February 8, 2023 at 12:09 pm #7182AdrianKeymasterYes, you can write a new post processor to do that. Your outlined approach looks workable.
However, I would suggest to not use the legacy (non-GPU-supported) post processors used by
setFreeEnergyWallBoundary
as a blueprint but e.g. the style used insetInterpolatedVelocityBoundary
. Such a new post processor is more simple and runs on all supported platforms with good performance:struct ExamplePostProcessor { static constexpr OperatorScope scope = OperatorScope::PerCell; int getPriority() const { return 0; } template <typename CELL> void apply(CELL& cell) any_platform { // do something with the cell // neighbors can be accessed via <code>cell.neighbor(c_i)</code> } };
February 8, 2023 at 12:13 pm #7184AdrianKeymasterOn the dynamics: Dynamics don’t store data, they only model how the momenta are computed and the collision is performed.
You can set the population
iPop
of a “ghost” neighbor cell (commonly being assignedNoDynamics
, meaning they don’t perform any collision) in directionc
tovalue
using e.g.cell.neighbor(c)[iPop] = value;
. This will happen after the streaming step for normal post processors. If you need to execute this at a different time this is also straight forward to do as post processors are assigned to and executed at various stages in OpenLB.February 11, 2023 at 9:31 am #7192syedParticipantThank You, Adrian, for such an elaborate response. It will take some time and practice to comprehend the exact work.
As a second idea, I was thinking to implement the attractive force exerted by the wall (1/z^3) as an external force in the descriptor and the boundary will purely bounce back. It is possible? This way I might avoid writing my own post-processor for now, which I will surely write in some time. So do we have any analytical functor where I can add this z-dependent function as an external function to both of my lattices? Just like gravity in the rayleigh instability application.
And secondly, can we add thermal noise to our application? do we have this kind of dynamic also?February 17, 2023 at 10:09 am #7206FBukreevKeymasterHello,
you can write your own analytical function that depends on the z coordinate and then define the force with that functor. Here one example.
template <typename T, typename S, typename DESCRIPTOR> class PorosityProfil3D : public AnalyticalF3D<T, S> { private: T x0, x1, y0, y1, z0, z1, u_p; UnitConverter<T, DESCRIPTOR> const &converter; int iT, tempCase; public: PorosityProfil3D(T x0_, T x1_, T y0_, T y1_, T z0_, T z1_, T u_p_, int iT_, int tempCase_, UnitConverter<T, DESCRIPTOR> const &converter_) : AnalyticalF3D<T, S>(3), x0(x0_), x1(x1_), y0(y0_), y1(y1_), z0(z0_), z1(z1_), u_p(u_p_), iT(iT_), tempCase(tempCase_), converter(converter_) { this->getName() = "PorosityProfil3D"; }; bool operator()(T output[1], const S x[3]) { T res = converter.getResolution(); T gf = res / (res + 1); T distX = 2 * M_PI * (x[0] - tempCase * u_p * converter.getPhysTime(iT) - x0) / (x1 - x0) * gf; T distY = 2 * M_PI * (x[1] - tempCase * u_p * converter.getPhysTime(iT) - y0) / (y1 - y0) * gf; T distZ = 2 * M_PI * (x[2] - tempCase * u_p * converter.getPhysTime(iT) - y0) / (z1 - z0) * gf; output[0] = 0.5 + 0.4 * util::sin(distX) * util::sin(distY) * util::sin(distZ); return true; }; };
the x[2] is the z variable. For the force you need to change output[1] to the 3 dimensional output[3] array.
What do you mean under thermal noise? You can add advection diffusion equation for temperature scalar and couple it to the main equations.
Greetings
FedorMarch 1, 2023 at 9:41 pm #7250syedParticipantThank you fedor for your reply. is this example that you gave is present in current open LB version ? I am searching for this porosity profil3D . But 2 am not able to find it . will you please help.
March 2, 2023 at 10:28 am #7252FBukreevKeymasterYou can find something similar in the turbulent nozzle3d example. There is a turbulent inket velocity functor. What I wrote above is an example not from some specific case.
-
AuthorPosts
- You must be logged in to reply to this topic.