OpenLB 1.7
Loading...
Searching...
No Matches
particleSystem.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2021 Nicolas Hafen
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 PARTICLE_SYSTEM_HH
26#define PARTICLE_SYSTEM_HH
27
28
29namespace olb {
30
31namespace particles{
32
33template<typename T, typename PARTICLETYPE>
35 : _fieldGroupsContainer( Container<T,PARTICLETYPE,DATA>(0) ),
36 _serialSize(DATA(0).getSerializableSize())
37{}
38
39template<typename T, typename PARTICLETYPE>
41 : _fieldGroupsContainer( Container<T,PARTICLETYPE,DATA>(count) ),
42 _serialSize(DATA(0).getSerializableSize())
43{}
44
45template<typename T, typename PARTICLETYPE>
47 typename associatedTypes::template decompose_into<std::tuple> associatedData )
48 : _associatedData( associatedData ),
49 _fieldGroupsContainer( Container<T,PARTICLETYPE,DATA>(count) ),
50 _serialSize(DATA(0).getSerializableSize())
51{}
52
53template<typename T, typename PARTICLETYPE>
54template<typename PCONDITION>
56{
57 //Either directly return size of container
58 if constexpr(std::is_same_v<PCONDITION,conditions::all_particles>){
59 return _fieldGroupsContainer.size();
60 //Or iterate over container evaluating condition
61 } else {
62 std::size_t count=0;
63 for (std::size_t iP=0; iP<_fieldGroupsContainer.size(); ++iP) {
64 auto particle = get(iP);
65 doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>( particle,
66 [&](Particle<T,PARTICLETYPE> particle){ ++count; });
67 }
68 return count;
69 }
70}
71
72template<typename T, typename PARTICLETYPE>
73template<typename PCONDITION>
74constexpr std::size_t ParticleSystem<T, PARTICLETYPE>::size(int globiC)
75{
76 //Either directly return size of container
77 if constexpr(std::is_same_v<PCONDITION,conditions::all_particles>){
78 return _fieldGroupsContainer.size();
79 //Or iterate over container evaluating condition
80 } else {
81 std::size_t count=0;
82 for (std::size_t iP=0; iP<_fieldGroupsContainer.size(); ++iP) {
83 auto particle = get(iP);
84 doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>( particle,
85 [&](Particle<T,PARTICLETYPE> particle){ ++count; }, globiC);
86 }
87 return count;
88 }
89}
90
91template<typename T, typename PARTICLETYPE>
92template<bool boundsCheck>
94 unsigned iDyn)
95{
96 if constexpr(boundsCheck){
97 return _dynamicsVector.at(iDyn).get();
98 } else {
99 return _dynamicsVector[iDyn].get();
100 }
101}
102
103template<typename T, typename PARTICLETYPE>
105 std::shared_ptr<dynamics::ParticleDynamics<T,PARTICLETYPE>>& dynamicsSPtr )
106{
107 _dynamicsVector.push_back( dynamicsSPtr );
108}
109
110template<typename T, typename PARTICLETYPE>
111template <typename DYNAMICS, typename ...Args>
113 _dynamicsVector.push_back( std::make_shared<DYNAMICS>(std::forward<Args>(args)...) );
114}
115
116template<typename T, typename PARTICLETYPE>
118{
119 _fieldGroupsContainer.push_back();
120// _dynamicsMapContainer.push_back();
121}
122
123template<typename T, typename PARTICLETYPE>
124void ParticleSystem<T,PARTICLETYPE>::swapParticles(std::size_t iP, std::size_t jP)
125{
126 _fieldGroupsContainer.swapElements(iP,jP);
127// _dynamicsMapContainer.swapElements(iP,jP);
128}
129
130template<typename T, typename PARTICLETYPE>
132 std::size_t iP0, std::size_t iPmax, T timeStepSize, unsigned iDyn )
133{
134 auto particle = get(iP0);
135 for (std::size_t iP=iP0; iP<iPmax; ++iP) {
136 particle.process(timeStepSize,iDyn);
137 particle.advanceId();
138 }
139}
140
141template<typename T, typename PARTICLETYPE>
142void ParticleSystem<T,PARTICLETYPE>::process(T timeStepSize, unsigned iDyn)
143{
144 process(0, size(), timeStepSize, iDyn);
145}
146
147
148template<typename T, typename PARTICLETYPE>
150{
151 return _fieldGroupsContainer;
152}
153
154template<typename T, typename PARTICLETYPE>
155std::vector<std::shared_ptr<dynamics::ParticleDynamics<T,PARTICLETYPE>>>& ParticleSystem<T,PARTICLETYPE>::getDynamicsVector()
156{
157 return _dynamicsVector;
158}
159
160template<typename T, typename PARTICLETYPE>
161template<bool boundsCheck>
163{
164 if constexpr(boundsCheck){
165 if (iParticle>_fieldGroupsContainer.size()){
166 throw std::out_of_range("Particle does not exist in Particlesystem!");
167 }
168 return Particle<T,PARTICLETYPE>( _fieldGroupsContainer.data(),
169 _dynamicsVector, iParticle );
170 } else {
171 return Particle<T,PARTICLETYPE>( _fieldGroupsContainer.data(),
172 _dynamicsVector, iParticle );
173 }
174}
175
176template<typename T, typename PARTICLETYPE>
178{
179 return get(iParticle);
180}
181
182template<typename T, typename PARTICLETYPE>
183template <typename GROUP, typename FIELD>
185{
186 using GROUP_EVAL = typename PARTICLETYPE::template derivedField<GROUP>;
187 using FIELD_EVAL = typename GROUP_EVAL::template derivedField<FIELD>;
188 return _fieldGroupsContainer.data().template get<GROUP_EVAL>()
189 .template get<FIELD_EVAL>();
190}
191
192template<typename T, typename PARTICLETYPE>
193template <typename GROUP, typename FIELD>
195{
196 using GROUP_EVAL = typename PARTICLETYPE::template derivedField<GROUP>;
197 using FIELD_EVAL = typename GROUP_EVAL::template derivedField<FIELD>;
198 return _fieldGroupsContainer.data().template get<GROUP_EVAL>()
199 .template get<FIELD_EVAL>()
200 .getRowPointer( iParticle );
201}
202
203template<typename T, typename PARTICLETYPE>
204template<typename TYPE>
206{
207 const std::size_t idx = associatedTypes::template index<TYPE>();
208 return std::get<idx>(_associatedData);
209}
210
211
212template<typename T, typename PARTICLETYPE>
214{
215 return _serialSize;
216}
217
218template<typename T, typename PARTICLETYPE>
220{
221 OstreamManager clout(std::cout, "ParticleSystem");
222 clout << "-----ParticleSystem------" << std::endl;
223 clout << "nop=" << size() << std::endl;
224 clout << "-------------------------" << std::endl;
225}
226
227template<typename T, typename PARTICLETYPE>
229{
230 //Check, whether at least one ParticleDynamics present
231 if ( _dynamicsVector.size()==0 ){
232 throw std::logic_error("No ParticleDynamics set!");
233 }
234}
235
236} //namespace particles
237
238} //namespace olb
239
240
241#endif
Container is a std::vector inspired data wrapper that allows for simple content manipulation of its o...
Definition container.h:44
Storage for dynamic field groups (Prototype for ParticleSystem)
class for marking output with some text
void process(std::size_t p0, std::size_t p1, T timeStepSize, unsigned iDyn=0)
Upate/process particle quantities on a subset (mostly local equivalent to collide)
auto & get()
Expose container.
Particle< T, PARTICLETYPE > operator[](std::size_t iParticle)
Create and return particle with operator[].
void swapParticles(std::size_t iP, std::size_t jP)
Swap particles by index.
std::vector< std::shared_ptr< dynamics::ParticleDynamics< T, PARTICLETYPE > > > & getDynamicsVector()
Expose dynamics vector.
dynamics::ParticleDynamics< T, PARTICLETYPE > * getDynamics(unsigned iDyn=0)
Get specific dynamics (optional boundsCheck via .at())
void checkForErrors()
Check for erroes.
constexpr std::size_t size()
Size of ParticleSystem.
void print()
Print relevant infos.
void defineDynamics(Args &&...args)
Define dynamics (factory method)
auto & getAssociatedData()
Get associated data by specifying data type.
void extend()
Extend particle system by one particle.
void addDynamics(std::shared_ptr< dynamics::ParticleDynamics< T, PARTICLETYPE > > &dynamicsSPtr)
Add dynamics (from shared_pointer of dynamics)
ParticleSystem()
Default constructor.
auto getFieldPointer(std::size_t iParticle)
Get FieldPointer by GROUP (or base of GROUP) and FIELD for specific iParticle.
std::size_t getSerialSize() const
Get serial size of dynamic fields group.
auto & getFieldD()
Get whole Field by GROUP (or base of GROUP) and FIELD.
Top level namespace for all of OpenLB.