OpenLB 1.7
Loading...
Searching...
No Matches
lambdaLoops.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2022 Nicolas Hafen, Mathias J. Krause
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
25#ifndef LAMBDA_LOOPS_H
26#define LAMBDA_LOOPS_H
27
28
29namespace olb {
30
31namespace particles {
32
33
34
35//Do for particle
36template<typename T, typename PARTICLETYPE, typename F>
38 Particle<T,PARTICLETYPE>& particle, F f)
39{
40 if constexpr (std::is_invocable_v<F,Particle<T,PARTICLETYPE>&>){
41 f( particle );
42 } else {
43 f();
44 }
45}
46
47
48//Do for particle satisfying the provided particle condition
49//- Provides dynamic and static support for
50// - PCONDITION::value(particle)
51// - f(particle)
52// - f()
53//- Note: "conditions::all_particles" is faster, when applicable
54template<typename T, typename PARTICLETYPE, typename PCONDITION=conditions::valid_particles, typename F>
57 F f )
58{
59 //Check whether dynamic (constexpression value not possible)
60 if constexpr (PCONDITION::dynamic){
61 if ( PCONDITION::template value<T,PARTICLETYPE>(particle) ){
62 doForParticle( particle, f);
63 }
64 }
65 //Use static constexpression value
66 //- for now, implies no template use
67 else {
68 if constexpr (PCONDITION::value){
69 doForParticle( particle, f);
70 }
71 }
72}
73
74//Do for particle satisfying the provided particle condition
75//- Provides dynamic and static support for
76// - PCONDITION::value(particle)
77// - PCONDITION::value(particle,globiC)
78// - f(particle)
79// - f()
80//- Note: "conditions::all_particles" is faster, when applicable
81template<typename T, typename PARTICLETYPE, typename PCONDITION=conditions::valid_particles, typename F>
84 F f, int globiC )
85{
86 //Check whether dynamic (constexpression value not possible)
87 if constexpr (PCONDITION::dynamic){
88 //Check whether globiC has to be passed
89 if constexpr (std::is_invocable_v<decltype(PCONDITION::template value<T,PARTICLETYPE>),
91 if ( PCONDITION::template value<T,PARTICLETYPE>(particle,globiC) ){
92 if constexpr (std::is_invocable_v<F,Particle<T,PARTICLETYPE>&>){
93 f( particle );
94 } else {
95 f();
96 }
97 }
98 } else {
99 //Call without globiC
100 if ( PCONDITION::template value<T,PARTICLETYPE>(particle) ){
101 doForParticle( particle, f);
102 }
103 }
104 }
105 //Use static constexpression value
106 else {
107 //Call without globiC
108 if constexpr (PCONDITION::value){
109 doForParticle( particle, f);
110 }
111 }
112}
113
114
115
116//Iterate over particles in particle system satisfying the provided particle condition
117template<typename T, typename PARTICLETYPE, typename PCONDITION=conditions::valid_particles, typename F>
119 ParticleSystem<T,PARTICLETYPE>& particleSystem,
120 F f, int globiC )
121{
122 for (std::size_t iP=0; iP<particleSystem.size(); ++iP) {
123 auto particle = particleSystem.get(iP);
124 //Execute F when particle meets condition
125 doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>( particle,
126 [&](Particle<T,PARTICLETYPE> particle){
127 f( particle );
128 }, globiC );
129 }
130}
131
132//Iterate over particles in particle system satisfying the provided particle condition
133//- no globiC required
134template<typename T, typename PARTICLETYPE, typename PCONDITION=conditions::valid_particles, typename F>
136 ParticleSystem<T,PARTICLETYPE>& particleSystem,
137 F f )
138{
139 for (std::size_t iP=0; iP<particleSystem.size(); ++iP) {
140 auto particle = particleSystem.get(iP);
141 //Execute F when particle meets condition
142 doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>( particle,
143 [&](Particle<T,PARTICLETYPE> particle){
144 f( particle );
145 });
146 }
147}
148
149
150namespace communication {
151
152//Iterator over super particle system
153template<typename T, typename PARTICLETYPE, typename F>
156 F f )
157{
158 //Retrieve load balancer
159 auto& loadBalancer = sParticleSystem.getSuperStructure().getLoadBalancer();
160 //Loop over iCs
161 for (int iC=0; iC<loadBalancer.size(); ++iC){
162 int globiC = loadBalancer.glob(iC);
163 //Retrieve container
164 auto bParticleSystems = sParticleSystem.getBlockParticleSystems();
165 auto& particleSystem = *bParticleSystems[iC];
166 f( particleSystem, iC, globiC );
167 }
168}
169
170
171//Iterate over particles in super particle system
172template<typename T, typename PARTICLETYPE, typename PCONDITION=conditions::valid_particles, typename F>
175 F f )
176{
177 //Iterate over particle systems
178 forSystemsInSuperParticleSystem( sParticleSystem,
179 [&](ParticleSystem<T,PARTICLETYPE>& particleSystem, int iC, int globiC){
180 //Iterate over particles
181 forParticlesInParticleSystem<T,PARTICLETYPE,PCONDITION>( particleSystem,
182 [&](Particle<T,PARTICLETYPE>& particle){
183 if constexpr (std::is_invocable_v<F,
185 {
186 f( particle, particleSystem, globiC );
187 } else {
188 f( particle );
189 }
190 },globiC);
191 });
192}
193
194//Do for particle in superParticleSystem
195//- enables retrieval via particle locator, hence circumvents
196// having to search for a speficic particle again
197template<typename T, typename PARTICLETYPE, typename F>
200 ParallelParticleLocator& locator, F f)
201{
202 //Retrieve rank and only proceed for correct one
203 int rank = singleton::mpi().getRank();
204 auto& loadBalancer = sParticleSystem.getSuperStructure().getLoadBalancer();
205 if (rank==loadBalancer.rank(locator.globiC)){
206 //Retrieve ParticleSystem
207 auto bParticleSystems = sParticleSystem.getBlockParticleSystems();
208 auto& particleSystem = *bParticleSystems[loadBalancer.loc(locator.globiC)];
209 //Retrieve particle
210 auto particle = particleSystem.get(locator.localID);
211 //Call function f for particle
212 doForParticle( particle, f );
213 }
214}
215
216
217
218} //namespace communication
219
220
226template<typename T, typename PARTICLETYPE, typename PCONDITION=conditions::valid_particles, typename F>
228 XParticleSystem<T,PARTICLETYPE>& xParticleSystem,
229 F f )
230{
231 if constexpr( access::providesParallelization<PARTICLETYPE>() ){
232 //Iterate over particle systems
234 [&](ParticleSystem<T,PARTICLETYPE>& particleSystem, int iC, int globiC){
235 //Iterate over particles
236 forParticlesInParticleSystem<T,PARTICLETYPE,PCONDITION>( particleSystem,
237 [&](Particle<T,PARTICLETYPE>& particle){
238 if constexpr (std::is_invocable_v<F,
240 {
241 f( particle, particleSystem, globiC );
242 } else {
243 f( particle );
244 }
245 },globiC);
246 });
247 } else {
248 //Loop over all particles
249 forParticlesInParticleSystem<T,PARTICLETYPE,PCONDITION>( xParticleSystem,
250 [&](Particle<T,PARTICLETYPE>& particle){
251 if constexpr (std::is_invocable_v<F,
253 {
254 f( particle, xParticleSystem, 0 );
255 } else {
256 f( particle );
257 }
258 });
259 }
260}
261
262
263
264
265
266} //namespace particles
267
268} //namespace olb
269
270
271#endif
LoadBalancer< T > & getLoadBalancer()
Read and write access to the load balancer.
auto & get()
Expose container.
constexpr std::size_t size()
Size of ParticleSystem.
SuperStructure< T, PARTICLETYPE::d > & getSuperStructure()
std::vector< ParticleSystem< T, PARTICLETYPE > * > & getBlockParticleSystems()
int getRank() const
Returns the process ID.
void forSystemsInSuperParticleSystem(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, F f)
void doForParticle(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, ParallelParticleLocator &locator, F f)
void forParticlesInSuperParticleSystem(SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem, F f)
std::conditional_t< PARTICLETYPE::template providesNested< descriptors::PARALLELIZATION >(), SuperParticleSystem< T, PARTICLETYPE >, ParticleSystem< T, PARTICLETYPE > > XParticleSystem
void doForParticle(Particle< T, PARTICLETYPE > &particle, F f)
Definition lambdaLoops.h:37
void doWhenMeetingCondition(Particle< T, PARTICLETYPE > &particle, F f)
Definition lambdaLoops.h:55
void forParticlesInParticleSystem(ParticleSystem< T, PARTICLETYPE > &particleSystem, F f, int globiC)
void forParticlesInXParticleSystem(XParticleSystem< T, PARTICLETYPE > &xParticleSystem, F f)
Iterate over particles in x particle system.
MpiManager & mpi()
Top level namespace for all of OpenLB.