OpenLB 1.8.1
Loading...
Searching...
No Matches
boundaryPostProcessors2D.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2006, 2007 Jonas Latt
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 * Generic version of the collision, which modifies the particle
9 * distribution functions, by Orestis Malaspinas.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public
22 * License along with this program; if not, write to the Free
23 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 * Boston, MA 02110-1301, USA.
25*/
26
27#ifndef FD_BOUNDARIES_2D_H
28#define FD_BOUNDARIES_2D_H
29
30#include "core/postProcessing.h"
31
32#include "core/operator.h"
33
34namespace olb {
35
41template <typename T, typename DESCRIPTOR, int direction, int orientation>
43public:
45
46 int getPriority() const { return 0; }
47
48 template <concepts::DynamicCell CELL>
49 void apply(CELL& cell) any_platform;
50
51private:
52 template <int deriveDirection, typename CELL, typename V=CELL::value_t>
53 void interpolateGradients(CELL& blockLattice, V velDeriv[DESCRIPTOR::d]) const any_platform;
54};
55
64template<typename T, typename DESCRIPTOR, int NORMAL_X, int NORMAL_Y>
66public:
68
69 int getPriority() const {
70 return 0;
71 }
72
73 template <concepts::DynamicCell CELL>
74 void apply(CELL& cell) any_platform {
75
76 cell.template setField<descriptors::CHEM_POTENTIAL>(
77 cell.neighbor({-NORMAL_X,-NORMAL_Y}).template getField<descriptors::CHEM_POTENTIAL>());
78
79 T rho0 = cell.computeRho();
80 T rho1 = cell.neighbor({-NORMAL_X,-NORMAL_Y}).computeRho();
81
82 cell.template setField<descriptors::CHEM_POTENTIAL>(
83 cell.template getField<descriptors::CHEM_POTENTIAL>() + (rho1 / rho0 - 1) / descriptors::invCs2<T,DESCRIPTOR>());
84
85 }
86
87};
88
89template<typename T, typename DESCRIPTOR, int NORMAL_X, int NORMAL_Y>
91public:
93
94 int getPriority() const {
95 return 0;
96 }
97
98 template <concepts::DynamicCell CELL>
99 void apply(CELL& cell) any_platform {
100
101 cell.template setField<descriptors::CHEM_POTENTIAL>(
102 cell.neighbor({-NORMAL_X,-NORMAL_Y}).template getField<descriptors::CHEM_POTENTIAL>());
103
104 }
105
106};
107
108template<typename T, typename DESCRIPTOR, int NORMAL_X, int NORMAL_Y>
110public:
112
113 int getPriority() const {
114 return 0;
115 }
116
117 template <concepts::DynamicCell CELL>
118 void apply(CELL& cell) any_platform {
119
120 T rhoBoundaryNew, rhoBoundaryOld, rhoBulk, u[2];
121
122 rhoBoundaryOld = cell.computeRho();
123
124 cell.neighbor({-NORMAL_X,-NORMAL_Y}).computeRhoU(rhoBulk, u);
125
126 T uPerp = 0;
127
128 Vector<T,2> normalVec({NORMAL_X,NORMAL_Y});
129
130 if (normalVec[0] == 0) {
131 uPerp = normalVec[1] * u[1];
132 } else if (normalVec[1] == 0) {
133 uPerp = normalVec[0] * u[0];
134 }
135
136 rhoBoundaryNew = (rhoBoundaryOld + uPerp * rhoBulk) / (1. + uPerp);
137 cell.defineRho(rhoBoundaryNew);
138
139 cell.template setField<descriptors::CHEM_POTENTIAL>(
140 cell.neighbor({-NORMAL_X,-NORMAL_Y}).template getField<descriptors::CHEM_POTENTIAL>());
141
142 cell.template setField<descriptors::CHEM_POTENTIAL>(
143 cell.template getField<descriptors::CHEM_POTENTIAL>() + (rhoBulk / rhoBoundaryNew - 1) / descriptors::invCs2<T,DESCRIPTOR>());
144
145 }
146
147};
148
149template<typename T, typename DESCRIPTOR, int NORMAL_X, int NORMAL_Y>
151public:
153
154 int getPriority() const {
155 return 0;
156 }
157
158 template <concepts::DynamicCell CELL>
159 void apply(CELL& cell) any_platform {
160
161 T rhoBoundaryNew, rhoBoundaryOld, rhoBulk, u[2];
162
163 rhoBoundaryOld = cell.computeRho();
164
165 cell.neighbor({-NORMAL_X,-NORMAL_Y}).computeRhoU(rhoBulk, u);
166
167 T uPerp = 0;
168
169 Vector<T,2> normalVec({NORMAL_X,NORMAL_Y});
170
171 if (normalVec[0] == 0) {
172 uPerp = normalVec[1] * u[1];
173 } else if (normalVec[1] == 0) {
174 uPerp = normalVec[0] * u[0];
175 }
176
177 rhoBoundaryNew = (rhoBoundaryOld + uPerp * rhoBulk) / (1. + uPerp);
178 cell.defineRho(rhoBoundaryNew);
179
180 cell.template setField<descriptors::CHEM_POTENTIAL>(
181 cell.neighbor({-NORMAL_X,-NORMAL_Y}).template getField<descriptors::CHEM_POTENTIAL>());
182
183 }
184
185};
186
187
192template<typename T, typename DESCRIPTOR, int NORMAL_X, int NORMAL_Y>
194
195public:
198
199 int getPriority() const {
200 return 0;
201 }
202
203 template <concepts::DynamicCell CELL, typename PARAMETERS>
204 void apply(CELL& cell, PARAMETERS& parameters) any_platform{
205
206 auto addend = parameters.template get<descriptors::ADDEND>();
207
208 T rhoBulk = cell.neighbor({-NORMAL_X,-NORMAL_Y}).computeRho();
209 T rhoTmp = 0.;
210
211 for (int iPop = 1; iPop < DESCRIPTOR::q ; ++iPop) {
212 rhoTmp += cell[iPop];
213 }
214
215 T rhoBoundary = rhoBulk + addend;
216 rhoBoundary -= rhoTmp;
217
218 cell[0] = rhoBoundary - 1.;
219
220 cell.template setField<descriptors::CHEM_POTENTIAL>(
221 cell.neighbor({-NORMAL_X,-NORMAL_Y}).template getField<descriptors::CHEM_POTENTIAL>());
222
223 cell.template setField<descriptors::CHEM_POTENTIAL>(
224 cell.template getField<descriptors::CHEM_POTENTIAL>() + (rhoBulk / rhoBoundary - 1) / descriptors::invCs2<T,DESCRIPTOR>());
225
226 }
227
228};
229
230template<typename T, typename DESCRIPTOR, int NORMAL_X, int NORMAL_Y>
232public:
235
236 int getPriority() const {
237 return 0;
238 }
239
240 template <concepts::DynamicCell CELL, typename PARAMETERS>
241 void apply(CELL& cell, PARAMETERS& parameters) any_platform{
242
243 auto addend = parameters.template get<descriptors::ADDEND>();
244
245 T rhoBulk = cell.neighbor({-NORMAL_X,-NORMAL_Y}).computeRho();
246 T rhoTmp = 0.;
247
248 for (int iPop = 1; iPop < DESCRIPTOR::q ; ++iPop) {
249 rhoTmp += cell[iPop];
250 }
251
252 T rhoBoundary = rhoBulk + addend;
253 rhoBoundary -= rhoTmp;
254
255 cell[0] = rhoBoundary - 1.;
256
257 cell.template setField<descriptors::CHEM_POTENTIAL>(
258 cell.neighbor({-NORMAL_X,-NORMAL_Y}).template getField<descriptors::CHEM_POTENTIAL>());
259
260 }
261
262};
263
267template <typename T, typename DESCRIPTOR, int NORMAL_X, int NORMAL_Y>
269public:
271
272 int getPriority() const {
273 return 0;
274 }
275
276 template <concepts::DynamicCell CELL>
277 void apply(CELL& cell) any_platform;
278};
279
283template <typename T, typename DESCRIPTOR, int direction, int orientation>
285public:
287
290 util::populationsContributingToVelocity<DESCRIPTOR, direction,
291 -orientation>()
292 .size()> {};
293
294 int getPriority() const {
295 return 0;
296 }
297
298 template <concepts::DynamicCell CELL>
299 void initialize(CELL& cell) any_platform;
300
301 template <concepts::DynamicCell CELL>
302 void apply(CELL& cell) any_platform;
303};
304
309template <typename T, typename DESCRIPTOR>
310class SlipBoundaryProcessor2D : public LocalPostProcessor2D<T, DESCRIPTOR> {
311public:
312 SlipBoundaryProcessor2D(int x0_, int x1_, int y0_, int y1_,
313 int discreteNormalX_, int discreteNormalY_);
314 int extent() const override { return 0; }
315 int extent(int whichDirection) const override { return 0; }
316 void process(BlockLattice<T, DESCRIPTOR>& blockLattice) override;
317 void processSubDomain(BlockLattice<T, DESCRIPTOR>& blockLattice, int x0_,
318 int x1_, int y0_, int y1_) override;
319
320private:
321 int reflectionPop[DESCRIPTOR::q];
322 int x0, x1, y0, y1;
323};
324
325template <typename T, typename DESCRIPTOR>
327 : public PostProcessorGenerator2D<T, DESCRIPTOR> {
328public:
329 SlipBoundaryProcessorGenerator2D(int x0_, int x1_, int y0_, int y1_,
330 int discreteNormalX_, int discreteNormalY_);
333
334private:
335 int discreteNormalX;
336 int discreteNormalY;
337};
338
339
345template <typename T, typename DESCRIPTOR, int xNormal, int yNormal>
347public:
349
350 int getPriority() const {
351 return 1;
352 }
353
354 template <concepts::DynamicCell CELL>
355 void apply(CELL& cell) any_platform;
356};
357
362template<typename T, typename DESCRIPTOR, int xNormal,int yNormal>
366
367 int getPriority() const {
368 return 0;
369 }
370
371 template <typename CELL, typename PARAMETERS>
372 void apply(CELL& cell, PARAMETERS& parameters) any_platform{
373
374 auto u_conv = parameters.template get<descriptors::MAX_VELOCITY>();
375 Vector<int,DESCRIPTOR::d> normal{-xNormal, -yNormal};
376 auto cell1 = cell.neighbor(normal);
377 auto outlet_cell = cell.template getField<descriptors::CONV_POPS>();
378
379 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
380 outlet_cell[iPop] = (outlet_cell[iPop] + u_conv * cell1[iPop]) / ((T)1 + u_conv);
381 cell[iPop] = outlet_cell[iPop];
382 }
383 cell.template setField<descriptors::CONV_POPS>(outlet_cell);
384 }
385
386};
387
392template<typename T, typename DESCRIPTOR, int xNormal,int yNormal>
396
397 int getPriority() const {
398 return 0;
399 }
400
401 template <typename CELL, typename PARAMETERS>
402 void apply(CELL& cell, PARAMETERS& parameters) any_platform{
403
404 auto u_conv = parameters.template get<descriptors::MAX_VELOCITY>();
405 Vector<int,DESCRIPTOR::d> normal{xNormal, yNormal};
406 auto outlet_cell = cell.template getField<descriptors::CONV_POPS>();
407
408 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
409 cell[iPop] = outlet_cell[iPop];
410 }
411
412 auto phi = cell.template getField<descriptors::STATISTIC>();
413 phi[0] = cell.computeRho();
414 cell.template setField<descriptors::STATISTIC>(phi);
415 auto phiGhost = cell.neighbor(normal).template getField<descriptors::STATISTIC>();
416 phiGhost[0] = (phiGhost[0] + u_conv * phi[0]) / ((T)1 + u_conv);
417 if (phiGhost[0] > 1.0001) phiGhost[0] = 1;
418 if (phiGhost[0] < -0.0001) phiGhost[0] = 0;
419 cell.neighbor(normal).template setField<descriptors::STATISTIC>(phiGhost);
420
421 Vector<int,DESCRIPTOR::d> tangent{yNormal, -xNormal};
422 if (cell.neighbor(tangent).template getField<descriptors::SCALAR>() == 2 ||
423 cell.neighbor(tangent).template getField<descriptors::BOUNDARY>() == 2) {
424 cell.neighbor(normal+tangent).template setField<descriptors::STATISTIC>(phiGhost);
425 }
426 tangent *= -1;
427 if (cell.neighbor(tangent).template getField<descriptors::SCALAR>() == 2 ||
428 cell.neighbor(tangent).template getField<descriptors::BOUNDARY>() == 2) {
429 cell.neighbor(normal+tangent).template setField<descriptors::STATISTIC>(phiGhost);
430 }
431 }
432
433};
434
439template<typename T, typename DESCRIPTOR>
442
443 int getPriority() const {
444 return 0;
445 }
446
447 template <typename CELL>
448 void apply(CELL& cell) any_platform{
449 auto outlet_cell = cell.template getField<descriptors::CONV_POPS>();
450 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
451 cell[iPop] = outlet_cell[iPop];
452 }
453 }
454
455};
456
457
458} // namespace olb
459
460#endif
PostProcessor for pressure / velocity outflow boundaries in the free energy model.
void apply(CELL &cell) any_platform
This class computes the skordos BC in 2D on a convex corner but with a limited number of terms added ...
Interface of 2D post-processing steps.
Definition aliases.h:43
This class computes a slip BC in 2D.
void processSubDomain(BlockLattice< T, DESCRIPTOR > &blockLattice, int x0_, int x1_, int y0_, int y1_) override
Execute post-processing step on a sublattice.
SlipBoundaryProcessor2D(int x0_, int x1_, int y0_, int y1_, int discreteNormalX_, int discreteNormalY_)
int extent(int whichDirection) const override
Extent of application area along a direction (0 or 1)
void process(BlockLattice< T, DESCRIPTOR > &blockLattice) override
Execute post-processing step.
int extent() const override
Extent of application area (0 for purely local operations)
PostProcessorGenerator2D< T, DESCRIPTOR > * clone() const override
PostProcessor2D< T, DESCRIPTOR > * generate() const override
SlipBoundaryProcessorGenerator2D(int x0_, int x1_, int y0_, int y1_, int discreteNormalX_, int discreteNormalY_)
This class computes a convection BC on a flat wall in 2D.
This class computes the skordos BC on a flat wall in 2D but with a limited number of terms added to t...
static constexpr OperatorScope scope
Plain old scalar vector.
constexpr T invCs2() any_platform
Definition functions.h:107
Top level namespace for all of OpenLB.
OperatorScope
Block-wide operator application scopes.
@ 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:77
Interface for post-processing steps – header file.
This class overcomes overwriting populations from streaming for convective boundary conditions.
void apply(CELL &cell) any_platform
static constexpr OperatorScope scope
This class computes the convective boundary condition for the populations of a phase field solving LB...
void apply(CELL &cell, PARAMETERS &parameters) any_platform
This class computes the convective boundary condition for phi at ghost nodes for a phase field solvin...
void apply(CELL &cell, PARAMETERS &parameters) any_platform
PostProcessors for the chemical potential boundary condition in the free energy model.
static constexpr OperatorScope scope
void apply(CELL &cell) any_platform
static constexpr OperatorScope scope
void apply(CELL &cell) any_platform
PostProcessor for the wetting boundary condition in the free energy model.
void apply(CELL &cell, PARAMETERS &parameters) any_platform
void apply(CELL &cell, PARAMETERS &parameters) any_platform
Base of a field whose size is defined by [C_0,C_1,C_2]^T * [1,D,Q].
Definition fields.h:52
Plain wrapper for list of types.
Definition meta.h:276