OpenLB 1.8.1
Loading...
Searching...
No Matches
setBoundary2D.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2021 Lennart Neukamm, Adrian Kummerlaender
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 SET_BOUNDARY_2D_H
25#define SET_BOUNDARY_2D_H
26
27namespace olb {
28
29//sets boundary on indicated cells. This is a function, which can be used on many boundaries.
30template<typename T, typename DESCRIPTOR>
31void setBoundary(BlockLattice<T,DESCRIPTOR>& block, int iX, int iY,
32 Dynamics<T,DESCRIPTOR>* dynamics,
34{
35 if (dynamics) {
36 block.defineDynamics({iX, iY}, dynamics);
37 auto cell = block.get(iX,iY);
38 dynamics->initialize(cell);
39 }
40 if (postProcessor && !block.isPadding({iX,iY})) {
41 block.addPostProcessor(*postProcessor);
42 }
43}
44
45template<typename T, typename DESCRIPTOR>
46void setBoundary(BlockLattice<T,DESCRIPTOR>& block, int iX, int iY,
47 Dynamics<T,DESCRIPTOR>* dynamics)
48{
49 if (dynamics) {
50 block.defineDynamics({iX, iY}, dynamics);
51 auto cell = block.get(iX,iY);
52 dynamics->initialize(cell);
53 }
54}
55
57template<typename T, typename DESCRIPTOR>
59{
60 /* local boundaries: _overlap = 0;
61 * interp boundaries: _overlap = 1;
62 * bouzidi boundaries: _overlap = 1;
63 * extField boundaries: _overlap = 1;
64 * advectionDiffusion boundaries: _overlap = 1;
65 */
66
67 if (_overlap == 0) {
68 return;
69 }
70
71 auto& communicator = sLattice.getCommunicator(stage::PostStream());
72 communicator.template requestField<descriptors::POPULATION>();
73
74 SuperGeometry<T,2>& superGeometry = indicator->getSuperGeometry();
75 for (int iCloc = 0; iCloc < sLattice.getLoadBalancer().size(); ++iCloc) {
76 const int nX = superGeometry.getBlockGeometry(iCloc).getNx();
77 const int nY = superGeometry.getBlockGeometry(iCloc).getNy();
78
79 for (int iX = -_overlap; iX < nX+_overlap; ++iX) {
80 for (int iY = -_overlap; iY < nY+_overlap; ++iY) {
81 if (iX < 0 || iX > nX - 1 ||
82 iY < 0 || iY > nY - 1 ) { // if within overlap
83 if (superGeometry.getBlockGeometry(iCloc).getMaterial(iX,iY) != 0) {
84 bool found = false;
85 for (int iXo = -_overlap; iXo <= _overlap && !found; ++iXo) {
86 for (int iYo = -_overlap; iYo <= _overlap && !found; ++iYo) {
87 const int nextX = iXo + iX;
88 const int nextY = iYo + iY;
89 if (indicator->getBlockIndicatorF(iCloc)(nextX, nextY)) {
90 communicator.requestCell({iCloc, iX, iY});
91 found = true;
92 }
93 }
94 }
95 }
96 }
97 }
98 }
99 }
100
101 communicator.exchangeRequests();
102}
103
104
105namespace boundaryhelper {
106
107//instatiates DYNAMICS with normal values form discreteNormal Vector n
108template <
109 typename T, typename DESCRIPTOR,
110 template<int...> typename DYNAMICS
111>
113{
114 if (n == Vector<int,2> {1, 1}) {
115 return DynamicsPromise(meta::id<DYNAMICS<1,1>>{});
116 }
117 else if (n == Vector<int,2> {1, -1}) {
118 return DynamicsPromise(meta::id<DYNAMICS<1,-1>>{});
119 }
120 else if (n == Vector<int,2> {-1, 1}) {
121 return DynamicsPromise(meta::id<DYNAMICS<-1,1>>{});
122 }
123 else if (n == Vector<int,2> {-1, -1}) {
124 return DynamicsPromise(meta::id<DYNAMICS<-1,-1>>{});
125 }
126 else {
127 throw std::runtime_error("Could not set Boundary.");
128 }
129}
130
131//instatiates DYNAMICS with direction and orientation values from discreteNormal Vector n
132template <
133 typename T, typename DESCRIPTOR,
134 template<int...> typename DYNAMICS
135>
137{
138 if (n[0] == 1) {
139 return DynamicsPromise(meta::id<DYNAMICS<0,1>>{});
140 }
141 else if (n[0] == -1) {
142 return DynamicsPromise(meta::id<DYNAMICS<0,-1>>{});
143 }
144 else if (n[1] == 1) {
145 return DynamicsPromise(meta::id<DYNAMICS<1,1>>{});
146 }
147 else if (n[1] == -1) {
148 return DynamicsPromise(meta::id<DYNAMICS<1,-1>>{});
149 }
150 else {
151 throw std::runtime_error("Could not set Boundary.");
152 }
153}
154
155//constructs DYNAMICS with a Momenta that expects a direction and orientation as template args
156template <
157 typename T, typename DESCRIPTOR,
158 template <typename,typename,typename> typename DYNAMICS,
159 template <int,int> typename MOMENTA
160>
162 template <int x, int y>
163 using ConcreteDynamics = DYNAMICS<T,DESCRIPTOR,MOMENTA<x,y>>;
164
168};
169
170//constructs DYNAMICS with a Momenta that expects two normal values a template args
171template <
172 typename T, typename DESCRIPTOR,
173 template <typename,typename,typename> typename DYNAMICS,
174 template <int,int> typename MOMENTA
175>
177 template <int x, int y>
178 using ConcreteDynamics = DYNAMICS<T,DESCRIPTOR,MOMENTA<x,y>>;
179
183};
184
185//constructs DYNAMICS with two normal values and a Momenta that itself expects two normal values
186template <
187 typename T, typename DESCRIPTOR,
188 template <typename,typename,typename,int,int> typename DYNAMICS,
189 template <int,int> typename MOMENTA
190>
192 template <int x, int y>
193 using ConcreteDynamics = DYNAMICS<T,DESCRIPTOR,MOMENTA<x,y>,x,y>;
194
198};
199
200//constructs DYNAMICS with template args MixinDynamics, two normal values and a momenta that expects two normal values
201template <
202 typename T, typename DESCRIPTOR,
203 template <typename,typename,typename,typename,int,int> typename DYNAMICS,
204 typename MIXIN,
205 template <int,int> typename MOMENTA
206>
208 template <int x, int y>
209 using ConcreteDynamics = DYNAMICS<T,DESCRIPTOR,MIXIN,MOMENTA<x,y>,x,y>;
210
214};
215
216//instantiates TYPE, derived from RESULT with values form descreteNormal Vector n
217//RESULT can be either Dynamics or PostProcessorGenerator2D
218template <
219 typename RESULT, typename T, typename DESCRIPTOR,
220 template <typename,typename,int,int> typename TYPE,
221 typename... ARGS
222>
223RESULT* constructForNormal(Vector<int,2> n, ARGS&&... args)
224{
225 if (n == Vector<int,2> {1, 1}) {
226 return new TYPE<T,DESCRIPTOR,1,1>(std::forward<decltype(args)>(args)...);
227 }
228 else if (n == Vector<int,2> {1, -1}) {
229 return new TYPE<T,DESCRIPTOR,1,-1>(std::forward<decltype(args)>(args)...);
230 }
231 else if (n == Vector<int,2> {-1, 1}) {
232 return new TYPE<T,DESCRIPTOR,-1,1>(std::forward<decltype(args)>(args)...);
233 }
234 else if (n == Vector<int,2> {-1, -1}) {
235 return new TYPE<T,DESCRIPTOR,-1,-1>(std::forward<decltype(args)>(args)...);
236 }
237 else {
238 throw std::runtime_error("Could not set Boundary.");
239 }
240}
241
242template <
243 typename RESULT, typename T, typename DESCRIPTOR,
244 template <int,int> typename TYPE
245>
247{
248 if (n == Vector<int,2> {1, 1}) {
249 return meta::id<TYPE<1,1>>();
250 }
251 else if (n == Vector<int,2> {1, -1}) {
252 return meta::id<TYPE<1,-1>>();
253 }
254 else if (n == Vector<int,2> {-1, 1}) {
255 return meta::id<TYPE<-1,1>>();
256 }
257 else if (n == Vector<int,2> {-1, -1}) {
258 return meta::id<TYPE<-1,-1>>();
259 }
260 else if (n == Vector<int,2> {-1, 0}) {
261 return meta::id<TYPE<-1,0>>();
262 }
263 else if (n == Vector<int,2> {1, 0}) {
264 return meta::id<TYPE<1,0>>();
265 }
266 else if (n == Vector<int,2> {0, -1}) {
267 return meta::id<TYPE<0,-1>>();
268 }
269 else if (n == Vector<int,2> {0, 1}) {
270 return meta::id<TYPE<0,1>>();
271 }
272 else {
273 throw std::runtime_error("Invalid normal");
274 }
275}
276
277template <
278 typename RESULT, typename T, typename DESCRIPTOR,
279 template <typename,typename,int,int> typename TYPE
280>
282{
283 if (n == Vector<int,2> {1, 1}) {
284 return meta::id<TYPE<T,DESCRIPTOR,1,1>>();
285 }
286 else if (n == Vector<int,2> {1, -1}) {
287 return meta::id<TYPE<T,DESCRIPTOR,1,-1>>();
288 }
289 else if (n == Vector<int,2> {-1, 1}) {
290 return meta::id<TYPE<T,DESCRIPTOR,-1,1>>();
291 }
292 else if (n == Vector<int,2> {-1, -1}) {
293 return meta::id<TYPE<T,DESCRIPTOR,-1,-1>>();
294 }
295 else if (n == Vector<int,2> {-1, 0}) {
296 return meta::id<TYPE<T,DESCRIPTOR,-1,0>>();
297 }
298 else if (n == Vector<int,2> {1, 0}) {
299 return meta::id<TYPE<T,DESCRIPTOR,1,0>>();
300 }
301 else if (n == Vector<int,2> {0, -1}) {
302 return meta::id<TYPE<T,DESCRIPTOR,0,-1>>();
303 }
304 else if (n == Vector<int,2> {0, 1}) {
305 return meta::id<TYPE<T,DESCRIPTOR,0,1>>();
306 }
307 else {
308 throw std::runtime_error("Invalid normal");
309 }
310}
311
312//constructs TYPE derived from PostProcessorGenerator2D with two normals as template args
313template <
314 typename T, typename DESCRIPTOR,
315 template <typename,typename,int,int> typename TYPE,
316 typename... ARGS
317>
319{
320 return constructForNormal<PostProcessorGenerator2D<T,DESCRIPTOR>,T,DESCRIPTOR,TYPE>(n, std::forward<decltype(args)>(args)...);
321}
322
323template <
324 typename T, typename DESCRIPTOR,
325 template<int...> typename TYPE
326>
331
332template <
333 typename T, typename DESCRIPTOR,
334 template<typename,typename,int,int> typename TYPE
335>
337{
338 return promiseForNormal<PostProcessorPromise<T,DESCRIPTOR>,T,DESCRIPTOR,TYPE>(n);
339}
340
341//instantiates TYPE, derived from RESULT with values form descreteNormal Vector n
342//RESULT can be either Dynamics or PostProcessorGenerator2D
343template <
344 typename RESULT, typename T, typename DESCRIPTOR,
345 template <typename,typename,int,int> typename TYPE,
346 typename... ARGS
347>
349{
350 if (n[0] == 1) {
351 return new TYPE<T,DESCRIPTOR,0,1>(std::forward<decltype(args)>(args)...);
352 }
353 else if (n[0] == -1) {
354 return new TYPE<T,DESCRIPTOR,0,-1>(std::forward<decltype(args)>(args)...);
355 }
356 else if (n[1] == 1) {
357 return new TYPE<T,DESCRIPTOR,1,1>(std::forward<decltype(args)>(args)...);
358 }
359 else if (n[1] == -1) {
360 return new TYPE<T,DESCRIPTOR,1,-1>(std::forward<decltype(args)>(args)...);
361 }
362 else {
363 throw std::runtime_error("Could not set Boundary.");
364 }
365}
366
367template <
368 typename PROMISE,
369 typename T, typename DESCRIPTOR,
370 template <typename,typename,int,int> typename TYPE
371>
373{
374 if (n[0] == 1) {
376 }
377 else if (n[0] == -1) {
378 return meta::id<TYPE<T,DESCRIPTOR,0,-1>>();
379 }
380 else if (n[1] == 1) {
382 }
383 else if (n[1] == -1) {
384 return meta::id<TYPE<T,DESCRIPTOR,1,-1>>();
385 }
386 else {
387 throw std::runtime_error("Invalid normal");
388 }
389}
390
391//constructs TYPE derived from PostProcessorGenerator2D with template args direction and orientation
392template <
393 typename T, typename DESCRIPTOR,
394 template <typename,typename,int,int> typename TYPE,
395 typename... ARGS
396>
401
402template <
403 typename T, typename DESCRIPTOR,
404 template <typename,typename,int,int> typename TYPE
405>
410
411}
412
413}
414
415#endif
Factory for instances of a specific Dynamics type.
Smart pointer for managing the various ways of passing functors around.
Definition functorPtr.h:60
Factory for instances of a specific OPERATOR type.
Representation of a statistic for a parallel 2D geometry.
BlockGeometry< T, D > & getBlockGeometry(int locIC)
Read and write access to a single block geometry.
Super class maintaining block lattices for a cuboid decomposition.
SuperCommunicator< T, SuperLattice > & getCommunicator(STAGE stage=STAGE())
Return communicator for given communication stage.
LoadBalancer< T > & getLoadBalancer()
Read and write access to the load balancer.
Plain old scalar vector.
DynamicsPromise< T, DESCRIPTOR > constructConcreteDynamicsForDirectionOrientation(Vector< int, 2 > n)
PostProcessorGenerator2D< T, DESCRIPTOR > * constructPostProcessorForNormal(Vector< int, 2 > n, ARGS &&... args)
PROMISE promiseForDirectionOrientation(Vector< int, 2 > n)
RESULT * constructForNormal(Vector< int, 2 > n, ARGS &&... args)
PostProcessorPromise< T, DESCRIPTOR > promisePostProcessorForNormal(Vector< int, 2 > n)
RESULT * constructForDirectionOrientation(Vector< int, 2 > n, ARGS &&... args)
RESULT promiseForNormal(Vector< int, 2 > n)
DynamicsPromise< T, DESCRIPTOR > constructConcreteDynamicsForNormal(Vector< int, 2 > n)
PostProcessorGenerator2D< T, DESCRIPTOR > * constructPostProcessorForDirectionOrientation(Vector< int, 2 > n, ARGS &&... args)
PostProcessorPromise< T, DESCRIPTOR > promisePostProcessorForDirectionOrientation(Vector< int, 2 > n)
Top level namespace for all of OpenLB.
void addPoints2CommBC(SuperLattice< T, DESCRIPTOR > &sLattice, FunctorPtr< SuperIndicatorF2D< T > > &&indicator, int _overlap)
Adds needed Cells to the Communicator _commBC in SuperLattice.
Vector(T &&t, Ts &&... ts) -> Vector< std::remove_cvref_t< T >, 1+sizeof...(Ts)>
DynamicsPromise(meta::id< DYNAMICS >) -> DynamicsPromise< typename DYNAMICS::value_t, typename DYNAMICS::descriptor_t >
void setBoundary(BlockLattice< T, DESCRIPTOR > &block, int iX, int iY, Dynamics< T, DESCRIPTOR > *dynamics, PostProcessorGenerator2D< T, DESCRIPTOR > *postProcessor)
Interface for per-cell dynamics.
Definition interface.h:56
virtual void initialize(Cell< T, DESCRIPTOR > &cell)
Initialize dynamics-specific data for cell.
Definition interface.h:70
DYNAMICS< T, DESCRIPTOR, MOMENTA< x, y >, x, y > ConcreteDynamics
DYNAMICS< T, DESCRIPTOR, MIXIN, MOMENTA< x, y >, x, y > ConcreteDynamics
DYNAMICS< T, DESCRIPTOR, MOMENTA< x, y > > ConcreteDynamics
DYNAMICS< T, DESCRIPTOR, MOMENTA< x, y > > ConcreteDynamics
Identity type to pass non-constructible types as value.
Definition meta.h:79
Communication after propagation.
Definition stages.h:36