OpenLB 1.7
Loading...
Searching...
No Matches
freeEnergyCoupling3D.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2018 Robin Trunk, Sam Avis
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24#ifndef FREE_ENERGY_COUPLING_3D_H
25#define FREE_ENERGY_COUPLING_3D_H
26
27namespace olb {
28
30
31 // Possible scope options: PerCell, PerBlock, PerCellWithParameters
33
34 struct ALPHA: public descriptors::FIELD_BASE<1> { };
35 struct KAPPA1: public descriptors::FIELD_BASE<1> { };
36 struct KAPPA2: public descriptors::FIELD_BASE<1> { };
37 struct KAPPA3: public descriptors::FIELD_BASE<1> { };
38
40
41 template <typename CELLS, typename PARAMETERS>
42 void apply(CELLS& cells, PARAMETERS& parameters) any_platform {
43
44 using V = typename CELLS::template value_t<names::A>::value_t;
45 using DESCRIPTOR = typename CELLS::template value_t<names::A>::descriptor_t;
46
47 // Get the cell of the first lattice
48 auto& cellA = cells.template get<names::A>();
49
50 // Get the cell of the second lattice
51 auto& cellB = cells.template get<names::B>();
52
53 V rhoA = cellA.computeRho();
54 V rhoB = cellB.computeRho();
55
56 V densitySum = rhoA + rhoB;
57 V densityDifference = rhoA - rhoB;
58
59 V kappa1 = parameters.template get<KAPPA1>();
60 V kappa2 = parameters.template get<KAPPA2>();
61
62 V term1 = 0.125 * kappa1 * (densitySum)
63 * (densitySum-1.) * (densitySum-2.);
64
65 V term2 = 0.125 * kappa2 * (densityDifference)
66 * (densityDifference-1.) * (densityDifference-2.);
67
68
69 V term3 = 0.;
70
71
72 V laplaceRho1 = -24.0 * rhoA;
73 V laplaceRho2 = -24.0 * rhoB;
74 V laplaceRho3 = 0;
75
76 for(int iPop=1; iPop<DESCRIPTOR::q; iPop++) {
77
78 auto nextCellA = cellA.neighbor(descriptors::c<DESCRIPTOR>(iPop));
79 auto nextCellB = cellB.neighbor(descriptors::c<DESCRIPTOR>(iPop));
80
81
82 V nextRhoA = nextCellA.computeRho();
83 V nextRhoB = nextCellB.computeRho();
84
85 if(iPop == 1 || iPop == 2 || iPop == 3 || iPop == 10 || iPop == 11 || iPop == 12) {
86 laplaceRho1 += (2 * nextRhoA);
87 laplaceRho2 += (2 * nextRhoB);
88 } else {
89 laplaceRho1 += nextRhoA;
90 laplaceRho2 += nextRhoB;
91 }
92 }
93
94 laplaceRho1 *= 1.0 / 6.0;
95 laplaceRho2 *= 1.0 / 6.0;
96
97 auto alpha = parameters.template get<ALPHA>();
98
99 cellA.template setField<descriptors::CHEM_POTENTIAL>(term1 + term2
100 + 0.25*alpha*alpha*( (kappa2 - kappa1) * laplaceRho2
101 +(kappa2 + kappa1) * (laplaceRho3 - laplaceRho1) ));
102
103 cellB.template setField<descriptors::CHEM_POTENTIAL>(term1 - term2
104 + 0.25*alpha*alpha*( (kappa2 - kappa1) * (laplaceRho1 - laplaceRho3)
105 -(kappa2 + kappa1) * laplaceRho2 ));
106
107 }
108
109};
110
111
112
113
115
116 // Possible scope options: PerCell, PerBlock, PerCellWithParameters
118
119 template <typename CELLS>
120 void apply(CELLS& cells) any_platform {
121
122 using V = typename CELLS::template value_t<names::A>::value_t;
123 using DESCRIPTOR = typename CELLS::template value_t<names::A>::descriptor_t;
124
125 // Get the cell of the first lattice
126 auto& cellA = cells.template get<names::A>();
127
128 // Get the cell of the second lattice
129 auto& cellB = cells.template get<names::B>();
130
131 V phi = cellA.computeRho();
132 V rho = cellB.computeRho();
133
134 // Calculatations for lattice A.
135 auto cellA1 = cellA.neighbor(descriptors::c<DESCRIPTOR>(1));
136 auto cellA2 = cellA.neighbor(descriptors::c<DESCRIPTOR>(2));
137 auto cellA3 = cellA.neighbor(descriptors::c<DESCRIPTOR>(3));
138 auto cellA4 = cellA.neighbor(descriptors::c<DESCRIPTOR>(4));
139 auto cellA5 = cellA.neighbor(descriptors::c<DESCRIPTOR>(5));
140 auto cellA6 = cellA.neighbor(descriptors::c<DESCRIPTOR>(6));
141 auto cellA7 = cellA.neighbor(descriptors::c<DESCRIPTOR>(7));
142 auto cellA8 = cellA.neighbor(descriptors::c<DESCRIPTOR>(8));
143 auto cellA9 = cellA.neighbor(descriptors::c<DESCRIPTOR>(9));
144 auto cellA10 = cellA.neighbor(descriptors::c<DESCRIPTOR>(10));
145 auto cellA11 = cellA.neighbor(descriptors::c<DESCRIPTOR>(11));
146 auto cellA12 = cellA.neighbor(descriptors::c<DESCRIPTOR>(12));
147 auto cellA13 = cellA.neighbor(descriptors::c<DESCRIPTOR>(13));
148 auto cellA14 = cellA.neighbor(descriptors::c<DESCRIPTOR>(14));
149 auto cellA15 = cellA.neighbor(descriptors::c<DESCRIPTOR>(15));
150 auto cellA16 = cellA.neighbor(descriptors::c<DESCRIPTOR>(16));
151 auto cellA17 = cellA.neighbor(descriptors::c<DESCRIPTOR>(17));
152 auto cellA18 = cellA.neighbor(descriptors::c<DESCRIPTOR>(18));
153
154 V gradMuPhiX = 1./12. * (
155 - cellA6.template getField<descriptors::CHEM_POTENTIAL>()
156 - cellA7.template getField<descriptors::CHEM_POTENTIAL>()
157 - cellA4.template getField<descriptors::CHEM_POTENTIAL>()
158 - 2 * cellA1.template getField<descriptors::CHEM_POTENTIAL>()
159 - cellA5.template getField<descriptors::CHEM_POTENTIAL>()
160 + cellA14.template getField<descriptors::CHEM_POTENTIAL>()
161 + 2 * cellA10.template getField<descriptors::CHEM_POTENTIAL>()
162 + cellA13.template getField<descriptors::CHEM_POTENTIAL>()
163 + cellA16.template getField<descriptors::CHEM_POTENTIAL>()
164 + cellA15.template getField<descriptors::CHEM_POTENTIAL>());
165
166 V gradMuPhiY = 1./12. * (
167 - cellA4.template getField<descriptors::CHEM_POTENTIAL>()
168 - cellA14.template getField<descriptors::CHEM_POTENTIAL>()
169 - cellA8.template getField<descriptors::CHEM_POTENTIAL>()
170 - 2 * cellA2.template getField<descriptors::CHEM_POTENTIAL>()
171 - cellA9.template getField<descriptors::CHEM_POTENTIAL>()
172 + cellA18.template getField<descriptors::CHEM_POTENTIAL>()
173 + 2 * cellA11.template getField<descriptors::CHEM_POTENTIAL>()
174 + cellA17.template getField<descriptors::CHEM_POTENTIAL>()
175 + cellA5.template getField<descriptors::CHEM_POTENTIAL>()
176 + cellA13.template getField<descriptors::CHEM_POTENTIAL>());
177
178 V gradMuPhiZ = 1./12. * (
179 - cellA8.template getField<descriptors::CHEM_POTENTIAL>()
180 - cellA18.template getField<descriptors::CHEM_POTENTIAL>()
181 - cellA6.template getField<descriptors::CHEM_POTENTIAL>()
182 - 2 * cellA3.template getField<descriptors::CHEM_POTENTIAL>()
183 - cellA16.template getField<descriptors::CHEM_POTENTIAL>()
184 + cellA7.template getField<descriptors::CHEM_POTENTIAL>()
185 + 2 * cellA12.template getField<descriptors::CHEM_POTENTIAL>()
186 + cellA15.template getField<descriptors::CHEM_POTENTIAL>()
187 + cellA9.template getField<descriptors::CHEM_POTENTIAL>()
188 + cellA17.template getField<descriptors::CHEM_POTENTIAL>());
189
190
191 // Calculatations for lattice B.
192 auto cellB1 = cellB.neighbor(descriptors::c<DESCRIPTOR>(1));
193 auto cellB2 = cellB.neighbor(descriptors::c<DESCRIPTOR>(2));
194 auto cellB3 = cellB.neighbor(descriptors::c<DESCRIPTOR>(3));
195 auto cellB4 = cellB.neighbor(descriptors::c<DESCRIPTOR>(4));
196 auto cellB5 = cellB.neighbor(descriptors::c<DESCRIPTOR>(5));
197 auto cellB6 = cellB.neighbor(descriptors::c<DESCRIPTOR>(6));
198 auto cellB7 = cellB.neighbor(descriptors::c<DESCRIPTOR>(7));
199 auto cellB8 = cellB.neighbor(descriptors::c<DESCRIPTOR>(8));
200 auto cellB9 = cellB.neighbor(descriptors::c<DESCRIPTOR>(9));
201 auto cellB10 = cellB.neighbor(descriptors::c<DESCRIPTOR>(10));
202 auto cellB11 = cellB.neighbor(descriptors::c<DESCRIPTOR>(11));
203 auto cellB12 = cellB.neighbor(descriptors::c<DESCRIPTOR>(12));
204 auto cellB13 = cellB.neighbor(descriptors::c<DESCRIPTOR>(13));
205 auto cellB14 = cellB.neighbor(descriptors::c<DESCRIPTOR>(14));
206 auto cellB15 = cellB.neighbor(descriptors::c<DESCRIPTOR>(15));
207 auto cellB16 = cellB.neighbor(descriptors::c<DESCRIPTOR>(16));
208 auto cellB17 = cellB.neighbor(descriptors::c<DESCRIPTOR>(17));
209 auto cellB18 = cellB.neighbor(descriptors::c<DESCRIPTOR>(18));
210
211 V gradMuRhoX = 1./12. * (
212 - cellB6.template getField<descriptors::CHEM_POTENTIAL>()
213 - cellB7.template getField<descriptors::CHEM_POTENTIAL>()
214 - cellB4.template getField<descriptors::CHEM_POTENTIAL>()
215 - 2 * cellB1.template getField<descriptors::CHEM_POTENTIAL>()
216 - cellB5.template getField<descriptors::CHEM_POTENTIAL>()
217 + cellB14.template getField<descriptors::CHEM_POTENTIAL>()
218 + 2 * cellB10.template getField<descriptors::CHEM_POTENTIAL>()
219 + cellB13.template getField<descriptors::CHEM_POTENTIAL>()
220 + cellB16.template getField<descriptors::CHEM_POTENTIAL>()
221 + cellB15.template getField<descriptors::CHEM_POTENTIAL>());
222
223 V gradMuRhoY = 1./12. * (
224 - cellB4.template getField<descriptors::CHEM_POTENTIAL>()
225 - cellB14.template getField<descriptors::CHEM_POTENTIAL>()
226 - cellB8.template getField<descriptors::CHEM_POTENTIAL>()
227 - 2 * cellB2.template getField<descriptors::CHEM_POTENTIAL>()
228 - cellB9.template getField<descriptors::CHEM_POTENTIAL>()
229 + cellB18.template getField<descriptors::CHEM_POTENTIAL>()
230 + 2 * cellB11.template getField<descriptors::CHEM_POTENTIAL>()
231 + cellB17.template getField<descriptors::CHEM_POTENTIAL>()
232 + cellB5.template getField<descriptors::CHEM_POTENTIAL>()
233 + cellB13.template getField<descriptors::CHEM_POTENTIAL>());
234
235 V gradMuRhoZ = 1./12. * (
236 - cellB8.template getField<descriptors::CHEM_POTENTIAL>()
237 - cellB18.template getField<descriptors::CHEM_POTENTIAL>()
238 - cellB6.template getField<descriptors::CHEM_POTENTIAL>()
239 - 2 * cellB3.template getField<descriptors::CHEM_POTENTIAL>()
240 - cellB16.template getField<descriptors::CHEM_POTENTIAL>()
241 + cellB7.template getField<descriptors::CHEM_POTENTIAL>()
242 + 2 * cellB12.template getField<descriptors::CHEM_POTENTIAL>()
243 + cellB15.template getField<descriptors::CHEM_POTENTIAL>()
244 + cellB9.template getField<descriptors::CHEM_POTENTIAL>()
245 + cellB17.template getField<descriptors::CHEM_POTENTIAL>());
246
247 V psi = 0.;
248 V gradMuPsiX = 0.;
249 V gradMuPsiY = 0.;
250 V gradMuPsiZ = 0.;
251
252 V forceX = - rho*gradMuRhoX - phi*gradMuPhiX - psi*gradMuPsiX;
253 V forceY = - rho*gradMuRhoY - phi*gradMuPhiY - psi*gradMuPsiY;
254 V forceZ = - rho*gradMuRhoZ - phi*gradMuPhiZ - psi*gradMuPsiZ;
255
256 cellB.template setField<descriptors::FORCE>({forceX, forceY, forceZ});
257
258 V u[3];
259 cellB.computeU(u);
260
261 cellA.template setField<descriptors::FORCE>(u);
262
263 }
264};
265
266
268
269 // Possible scope options: PerCell, PerBlock, PerCellWithParameters
271
272 template <typename CELLS>
273 void apply(CELLS& cells) any_platform {
274
275 using V = typename CELLS::template value_t<names::A>::value_t;
276 using DESCRIPTOR = typename CELLS::template value_t<names::A>::descriptor_t;
277
278 // Get the cell of the first lattice
279 auto& cellA = cells.template get<names::A>();
280
281 // Get the cell of the second lattice
282 auto& cellB = cells.template get<names::B>();
283
284 V u[DESCRIPTOR::d];
285 cellB.computeU(u);
286 cellA.defineU(u);
287 }
288};
289
290} // namespace olb
291
292#endif
Top level namespace for all of OpenLB.
OperatorScope
Block-wide operator application scopes.
Definition operator.h:54
@ PerCell
Per-cell application, i.e. OPERATOR::apply is passed a CELL concept implementation.
@ PerCellWithParameters
Per-cell application with parameters, i.e. OPERATOR::apply is passed a CELL concept implementation an...
#define any_platform
Define preprocessor macros for device-side functions, constant storage.
Definition platform.h:78
static constexpr OperatorScope scope
void apply(CELLS &cells, PARAMETERS &parameters) any_platform
void apply(CELLS &cells) any_platform
static constexpr OperatorScope scope
void apply(CELLS &cells) any_platform
static constexpr OperatorScope scope
Base of a field whose size is defined by [C,U_1,...,U_N]^T * [1,V_1,...V_N].
Plain wrapper for list of types.
Definition meta.h:276