OpenLB 1.7
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
28
29namespace olb {
30
31//sets boundary on indicated cells. This is a function, which can be used on many boundaries.
32template<typename T, typename DESCRIPTOR>
33void setBoundary(BlockLattice<T,DESCRIPTOR>& block, int iX, int iY,
34 Dynamics<T,DESCRIPTOR>* dynamics,
36{
37 if (dynamics) {
38 block.defineDynamics({iX, iY}, dynamics);
39 auto cell = block.get(iX,iY);
40 dynamics->initialize(cell);
41 }
42 if (postProcessor && !block.isPadding({iX,iY})) {
43 block.addPostProcessor(*postProcessor);
44 }
45}
46
47template<typename T, typename DESCRIPTOR>
48void setBoundary(BlockLattice<T,DESCRIPTOR>& block, int iX, int iY,
49 Dynamics<T,DESCRIPTOR>* dynamics)
50{
51 if (dynamics) {
52 block.defineDynamics({iX, iY}, dynamics);
53 auto cell = block.get(iX,iY);
54 dynamics->initialize(cell);
55 }
56}
57
59template<typename T, typename DESCRIPTOR>
61{
62 /* local boundaries: _overlap = 0;
63 * interp boundaries: _overlap = 1;
64 * bouzidi boundaries: _overlap = 1;
65 * extField boundaries: _overlap = 1;
66 * advectionDiffusion boundaries: _overlap = 1;
67 */
68
69 if (_overlap == 0) {
70 return;
71 }
72
73 auto& communicator = sLattice.getCommunicator(stage::PostStream());
74 communicator.template requestField<descriptors::POPULATION>();
75
76 SuperGeometry<T,2>& superGeometry = indicator->getSuperGeometry();
77 for (int iCloc = 0; iCloc < sLattice.getLoadBalancer().size(); ++iCloc) {
78 const int nX = superGeometry.getBlockGeometry(iCloc).getNx();
79 const int nY = superGeometry.getBlockGeometry(iCloc).getNy();
80
81 for (int iX = -_overlap; iX < nX+_overlap; ++iX) {
82 for (int iY = -_overlap; iY < nY+_overlap; ++iY) {
83 if (iX < 0 || iX > nX - 1 ||
84 iY < 0 || iY > nY - 1 ) { // if within overlap
85 if (superGeometry.getBlockGeometry(iCloc).getMaterial(iX,iY) != 0) {
86 bool found = false;
87 for (int iXo = -_overlap; iXo <= _overlap && !found; ++iXo) {
88 for (int iYo = -_overlap; iYo <= _overlap && !found; ++iYo) {
89 const int nextX = iXo + iX;
90 const int nextY = iYo + iY;
91 if (indicator->getBlockIndicatorF(iCloc)(nextX, nextY)) {
92 communicator.requestCell({iCloc, iX, iY});
93 found = true;
94 }
95 }
96 }
97 }
98 }
99 }
100 }
101 }
102
103 communicator.exchangeRequests();
104}
105
106
107namespace boundaryhelper {
108
109//instatiates DYNAMICS with normal values form discreteNormal Vector n
110template <
111 typename T, typename DESCRIPTOR,
112 template<int...> typename DYNAMICS
113>
115{
116 if (n == Vector<int,2> {1, 1}) {
117 return DynamicsPromise(meta::id<DYNAMICS<1,1>>{});
118 }
119 else if (n == Vector<int,2> {1, -1}) {
120 return DynamicsPromise(meta::id<DYNAMICS<1,-1>>{});
121 }
122 else if (n == Vector<int,2> {-1, 1}) {
123 return DynamicsPromise(meta::id<DYNAMICS<-1,1>>{});
124 }
125 else if (n == Vector<int,2> {-1, -1}) {
126 return DynamicsPromise(meta::id<DYNAMICS<-1,-1>>{});
127 }
128 else {
129 throw std::runtime_error("Could not set Boundary.");
130 }
131}
132
133//instatiates DYNAMICS with direction and orientation values from discreteNormal Vector n
134template <
135 typename T, typename DESCRIPTOR,
136 template<int...> typename DYNAMICS
137>
139{
140 if (n[0] == 1) {
141 return DynamicsPromise(meta::id<DYNAMICS<0,1>>{});
142 }
143 else if (n[0] == -1) {
144 return DynamicsPromise(meta::id<DYNAMICS<0,-1>>{});
145 }
146 else if (n[1] == 1) {
147 return DynamicsPromise(meta::id<DYNAMICS<1,1>>{});
148 }
149 else if (n[1] == -1) {
150 return DynamicsPromise(meta::id<DYNAMICS<1,-1>>{});
151 }
152 else {
153 throw std::runtime_error("Could not set Boundary.");
154 }
155}
156
157//constructs DYNAMICS with a Momenta that expects a direction and orientation as template args
158template <
159 typename T, typename DESCRIPTOR,
160 template <typename,typename,typename> typename DYNAMICS,
161 template <int,int> typename MOMENTA
162>
164 template <int x, int y>
165 using ConcreteDynamics = DYNAMICS<T,DESCRIPTOR,MOMENTA<x,y>>;
166
167 static auto construct(Vector<int,2> n) {
168 return constructConcreteDynamicsForDirectionOrientation<T,DESCRIPTOR,ConcreteDynamics>(n);
169 }
170};
171
172//constructs DYNAMICS with MixinDynamics and a Momenta that expects a direction and orientation as template args
173template <
174 typename T, typename DESCRIPTOR,
175 template <typename,typename,typename,typename> typename DYNAMICS,
176 typename MIXIN,
177 template <int,int> typename MOMENTA
178>
180 template <int x, int y>
181 using ConcreteDynamics = DYNAMICS<T,DESCRIPTOR,MIXIN,MOMENTA<x,y>>;
182
183 static auto construct(Vector<int,2> n) {
184 return constructConcreteDynamicsForDirectionOrientation<T,DESCRIPTOR,ConcreteDynamics>(n);
185 }
186};
187
188//constructs DYNAMICS with MixinDynamics, direction, orientation and a Momenta that itself expects a direction and orientation
189template <
190 typename T, typename DESCRIPTOR,
191 template <typename,typename,typename,typename,int,int> typename DYNAMICS,
192 typename MIXIN,
193 template <int,int> typename MOMENTA
194>
196 template <int x, int y>
197 using ConcreteDynamics = DYNAMICS<T,DESCRIPTOR,MIXIN,MOMENTA<x,y>,x,y>;
198
199 static auto construct(Vector<int,2> n) {
200 return constructConcreteDynamicsForDirectionOrientation<T,DESCRIPTOR,ConcreteDynamics>(n);
201 }
202};
203
204//constructs MixinDynamics with a Momenta that expects direction and orientation as template args
205template <
206 typename T, typename DESCRIPTOR,
207 typename MIXIN,
208 template <int,int> typename MOMENTA
209>
211 template <int x, int y>
212 using ConcreteDynamics = typename MIXIN::template exchange_momenta<MOMENTA<x,y>>;
213
214 static auto construct(Vector<int,2> n) {
215 return constructConcreteDynamicsForDirectionOrientation<T,DESCRIPTOR,ConcreteDynamics>(n);
216 }
217};
218
219//constructs DYNAMICS with a Momenta that expects two normal values a template args
220template <
221 typename T, typename DESCRIPTOR,
222 template <typename,typename,typename> typename DYNAMICS,
223 template <int,int> typename MOMENTA
224>
226 template <int x, int y>
227 using ConcreteDynamics = DYNAMICS<T,DESCRIPTOR,MOMENTA<x,y>>;
228
229 static auto construct(Vector<int,2> n) {
230 return constructConcreteDynamicsForNormal<T,DESCRIPTOR,ConcreteDynamics>(n);
231 }
232};
233
234//constructs DYNAMICS with two normal values and a Momenta that itself expects two normal values
235template <
236 typename T, typename DESCRIPTOR,
237 template <typename,typename,typename,int,int> typename DYNAMICS,
238 template <int,int> typename MOMENTA
239>
241 template <int x, int y>
242 using ConcreteDynamics = DYNAMICS<T,DESCRIPTOR,MOMENTA<x,y>,x,y>;
243
244 static auto construct(Vector<int,2> n) {
245 return constructConcreteDynamicsForNormal<T,DESCRIPTOR,ConcreteDynamics>(n);
246 }
247};
248
249//constructs DYNAMICS with template args MixinDynamics, two normal values and a momenta that expects two normal values
250template <
251 typename T, typename DESCRIPTOR,
252 template <typename,typename,typename,typename,int,int> typename DYNAMICS,
253 typename MIXIN,
254 template <int,int> typename MOMENTA
255>
257 template <int x, int y>
258 using ConcreteDynamics = DYNAMICS<T,DESCRIPTOR,MIXIN,MOMENTA<x,y>,x,y>;
259
260 static auto construct(Vector<int,2> n) {
261 return constructConcreteDynamicsForNormal<T,DESCRIPTOR,ConcreteDynamics>(n);
262 }
263};
264
265//instantiates TYPE, derived from RESULT with values form descreteNormal Vector n
266//RESULT can be either Dynamics or PostProcessorGenerator2D
267template <
268 typename RESULT, typename T, typename DESCRIPTOR,
269 template <typename,typename,int,int> typename TYPE,
270 typename... ARGS
271>
272RESULT* constructForNormal(Vector<int,2> n, ARGS&&... args)
273{
274 if (n == Vector<int,2> {1, 1}) {
275 return new TYPE<T,DESCRIPTOR,1,1>(std::forward<decltype(args)>(args)...);
276 }
277 else if (n == Vector<int,2> {1, -1}) {
278 return new TYPE<T,DESCRIPTOR,1,-1>(std::forward<decltype(args)>(args)...);
279 }
280 else if (n == Vector<int,2> {-1, 1}) {
281 return new TYPE<T,DESCRIPTOR,-1,1>(std::forward<decltype(args)>(args)...);
282 }
283 else if (n == Vector<int,2> {-1, -1}) {
284 return new TYPE<T,DESCRIPTOR,-1,-1>(std::forward<decltype(args)>(args)...);
285 }
286 else {
287 throw std::runtime_error("Could not set Boundary.");
288 }
289}
290
291template <
292 typename RESULT, typename T, typename DESCRIPTOR,
293 template <typename,typename,int,int> typename TYPE
294>
296{
297 if (n == Vector<int,2> {1, 1}) {
299 }
300 else if (n == Vector<int,2> {1, -1}) {
301 return meta::id<TYPE<T,DESCRIPTOR,1,-1>>();
302 }
303 else if (n == Vector<int,2> {-1, 1}) {
304 return meta::id<TYPE<T,DESCRIPTOR,-1,1>>();
305 }
306 else if (n == Vector<int,2> {-1, -1}) {
307 return meta::id<TYPE<T,DESCRIPTOR,-1,-1>>();
308 }
309 else if (n == Vector<int,2> {-1, 0}) {
310 return meta::id<TYPE<T,DESCRIPTOR,-1,0>>();
311 }
312 else if (n == Vector<int,2> {1, 0}) {
314 }
315 else if (n == Vector<int,2> {0, -1}) {
316 return meta::id<TYPE<T,DESCRIPTOR,0,-1>>();
317 }
318 else if (n == Vector<int,2> {0, 1}) {
320 }
321 else {
322 throw std::runtime_error("Invalid normal");
323 }
324}
325
326//constructs TYPE derived from PostProcessorGenerator2D with two normals as template args
327template <
328 typename T, typename DESCRIPTOR,
329 template <typename,typename,int,int> typename TYPE,
330 typename... ARGS
331>
333{
334 return constructForNormal<PostProcessorGenerator2D<T,DESCRIPTOR>,T,DESCRIPTOR,TYPE>(n, std::forward<decltype(args)>(args)...);
335}
336
337template <
338 typename T, typename DESCRIPTOR,
339 template<typename,typename,int,int> typename TYPE
340>
342{
343 return promiseForNormal<PostProcessorPromise<T,DESCRIPTOR>,T,DESCRIPTOR,TYPE>(n);
344}
345
346//instantiates TYPE, derived from RESULT with values form descreteNormal Vector n
347//RESULT can be either Dynamics or PostProcessorGenerator2D
348template <
349 typename RESULT, typename T, typename DESCRIPTOR,
350 template <typename,typename,int,int> typename TYPE,
351 typename... ARGS
352>
354{
355 if (n[0] == 1) {
356 return new TYPE<T,DESCRIPTOR,0,1>(std::forward<decltype(args)>(args)...);
357 }
358 else if (n[0] == -1) {
359 return new TYPE<T,DESCRIPTOR,0,-1>(std::forward<decltype(args)>(args)...);
360 }
361 else if (n[1] == 1) {
362 return new TYPE<T,DESCRIPTOR,1,1>(std::forward<decltype(args)>(args)...);
363 }
364 else if (n[1] == -1) {
365 return new TYPE<T,DESCRIPTOR,1,-1>(std::forward<decltype(args)>(args)...);
366 }
367 else {
368 throw std::runtime_error("Could not set Boundary.");
369 }
370}
371
372template <
373 typename PROMISE,
374 typename T, typename DESCRIPTOR,
375 template <typename,typename,int,int> typename TYPE
376>
378{
379 if (n[0] == 1) {
381 }
382 else if (n[0] == -1) {
383 return meta::id<TYPE<T,DESCRIPTOR,0,-1>>();
384 }
385 else if (n[1] == 1) {
387 }
388 else if (n[1] == -1) {
389 return meta::id<TYPE<T,DESCRIPTOR,1,-1>>();
390 }
391 else {
392 throw std::runtime_error("Invalid normal");
393 }
394}
395
396//constructs TYPE derived from PostProcessorGenerator2D with template args direction and orientation
397template <
398 typename T, typename DESCRIPTOR,
399 template <typename,typename,int,int> typename TYPE,
400 typename... ARGS
401>
403{
404 return constructForDirectionOrientation<PostProcessorGenerator2D<T,DESCRIPTOR>,T,DESCRIPTOR,TYPE>(n, std::forward<decltype(args)>(args)...);
405}
406
407template <
408 typename T, typename DESCRIPTOR,
409 template <typename,typename,int,int> typename TYPE
410>
412{
413 return promiseForDirectionOrientation<PostProcessorPromise<T,DESCRIPTOR>,T,DESCRIPTOR,TYPE>(n);
414}
415
416}//namespace boundaryhelper
417
418}//namespace olb
419
421
422#endif
Platform-abstracted block lattice for external access and inter-block interaction.
virtual void addPostProcessor(std::type_index stage, LatticeR< DESCRIPTOR::d > latticeR, PostProcessorPromise< T, DESCRIPTOR > &&promise)=0
Schedule post processor for application to latticeR in stage.
void defineDynamics(LatticeR< DESCRIPTOR::d > latticeR, DynamicsPromise< T, DESCRIPTOR > &&promise)
Assign promised DYNAMICS to latticeR.
Cell< T, DESCRIPTOR > get(CellID iCell)
Get Cell interface for index iCell.
bool isPadding(LatticeR< D > latticeR) const
Return whether location is valid.
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 POST_PROCESSOR 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.
Definition vector.h:47
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.
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:54
virtual void initialize(Cell< T, DESCRIPTOR > &cell)
Initialize dynamics-specific data for cell.
Definition interface.h:68
DYNAMICS< T, DESCRIPTOR, MIXIN, MOMENTA< x, y >, x, y > ConcreteDynamics
typename MIXIN::template exchange_momenta< MOMENTA< x, y > > ConcreteDynamics
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
DYNAMICS< T, DESCRIPTOR, MIXIN, MOMENTA< x, y > > ConcreteDynamics
Identity type to pass non-constructible types as value.
Definition meta.h:79
Communication after propagation.
Definition stages.h:36