SPHinXsys  alpha version
base_particles.hpp
Go to the documentation of this file.
1 /* -------------------------------------------------------------------------*
2  * SPHinXsys *
3  * --------------------------------------------------------------------------*
4  * SPHinXsys (pronunciation: s'finksis) is an acronym from Smoothed Particle *
5  * Hydrodynamics for industrial compleX systems. It provides C++ APIs for *
6  * physical accurate simulation and aims to model coupled industrial dynamic *
7  * systems including fluid, solid, multi-body dynamics and beyond with SPH *
8  * (smoothed particle hydrodynamics), a meshless computational method using *
9  * particle discretization. *
10  * *
11  * SPHinXsys is partially funded by German Research Foundation *
12  * (Deutsche Forschungsgemeinschaft) DFG HU1527/6-1, HU1527/10-1 *
13  * and HU1527/12-1. *
14  * *
15  * Portions copyright (c) 2017-2020 Technical University of Munich and *
16  * the authors' affiliations. *
17  * *
18  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
19  * not use this file except in compliance with the License. You may obtain a *
20  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
21  * *
22  * --------------------------------------------------------------------------*/
29 #ifndef BASE_PARTICLES_HPP
30 #define BASE_PARTICLES_HPP
31 
32 #include "base_particles.h"
34 
35 namespace SPH
36 {
37  //=================================================================================================//
38  template <typename VariableType>
39  void BaseParticles::
40  registerVariable(StdLargeVec<VariableType> &variable_addrs,
41  const std::string &variable_name, VariableType initial_value)
42  {
43  constexpr int type_index = DataTypeIndex<VariableType>::value;
44 
45  if (all_variable_maps_[type_index].find(variable_name) == all_variable_maps_[type_index].end())
46  {
47  variable_addrs.resize(real_particles_bound_, initial_value);
48  std::get<type_index>(all_particle_data_).push_back(&variable_addrs);
49  all_variable_maps_[type_index].insert(make_pair(variable_name, std::get<type_index>(all_particle_data_).size() - 1));
50  }
51  else
52  {
53  std::cout << "\n Error: the variable '" << variable_name << "' has already been registered!" << std::endl;
54  std::cout << __FILE__ << ':' << __LINE__ << std::endl;
55  exit(1);
56  }
57  }
58  //=================================================================================================//
59  template <typename VariableType, class InitializationFunction>
60  void BaseParticles::
61  registerVariable(StdLargeVec<VariableType> &variable_addrs,
62  const std::string &variable_name, const InitializationFunction &initialization)
63  {
64  constexpr int type_index = DataTypeIndex<VariableType>::value;
65 
66  registerVariable(variable_addrs, variable_name);
67  for (size_t i = 0; i != real_particles_bound_; ++i)
68  {
69  variable_addrs[i] = initialization(i);
70  }
71  }
72  //=================================================================================================//
73  template <typename VariableType>
74  StdLargeVec<VariableType> *BaseParticles::getVariableByName(const std::string &variable_name)
75  {
76  constexpr int type_index = DataTypeIndex<VariableType>::value;
77 
78  if (all_variable_maps_[type_index].find(variable_name) != all_variable_maps_[type_index].end())
79  return std::get<type_index>(all_particle_data_)[all_variable_maps_[type_index][variable_name]];
80 
81  std::cout << "\n Error: the variable '" << variable_name << "' is not registered!" << std::endl;
82  std::cout << __FILE__ << ':' << __LINE__ << std::endl;
83  exit(1);
84  return nullptr;
85  }
86  //=================================================================================================//
87  template <typename VariableType>
88  void BaseParticles::
89  addVariableNameToList(ParticleVariableList &variable_name_list, const std::string &variable_name)
90  {
91  constexpr int type_index = DataTypeIndex<VariableType>::value;
92 
93  if (all_variable_maps_[type_index].find(variable_name) != all_variable_maps_[type_index].end())
94  {
95  bool is_to_add = true;
96  for (size_t i = 0; i != variable_name_list[type_index].size(); ++i)
97  {
98  if (variable_name_list[type_index][i].first == variable_name)
99  is_to_add = false;
100  }
101  if (is_to_add)
102  {
103  size_t variable_index = all_variable_maps_[type_index][variable_name];
104  variable_name_list[type_index].push_back(make_pair(variable_name, variable_index));
105  }
106  }
107  else
108  {
109  std::cout << "\n Error: the variable '" << variable_name << "' to write is not particle data!" << std::endl;
110  std::cout << __FILE__ << ':' << __LINE__ << std::endl;
111  exit(1);
112  }
113  }
114  //=================================================================================================//
115  template <typename VariableType>
116  void BaseParticles::addVariableToWrite(const std::string &variable_name)
117  {
118  addVariableNameToList<VariableType>(variables_to_write_, variable_name);
119  }
120  //=================================================================================================//
121  template <class DerivedVariableMethod>
123  {
124  SimpleDynamics<DerivedVariableMethod> *derived_data = derived_particle_data_.createPtr<SimpleDynamics<DerivedVariableMethod>>(*sph_body_);
125  derived_variables_.push_back(derived_data);
126  using DerivedVariableType = typename DerivedVariableMethod::DerivedVariableType;
127  addVariableNameToList<DerivedVariableType>(variables_to_write_, derived_data->LocalDynamics().variable_name_);
128  }
129  //=================================================================================================//
130  template <typename VariableType>
131  void BaseParticles::addVariableToRestart(const std::string &variable_name)
132  {
133  addVariableNameToList<VariableType>(variables_to_restart_, variable_name);
134  }
135  //=================================================================================================//
136  template <typename VariableType>
137  void BaseParticles::addVariableToReload(const std::string &variable_name)
138  {
139  addVariableNameToList<VariableType>(variables_to_reload_, variable_name);
140  }
141  //=================================================================================================//
142  template <typename VariableType>
143  void BaseParticles::registerSortableVariable(const std::string &variable_name)
144  {
145  constexpr int type_index = DataTypeIndex<VariableType>::value;
146 
147  if (sortable_variable_maps_[type_index].find(variable_name) == sortable_variable_maps_[type_index].end())
148  {
149  if (all_variable_maps_[type_index].find(variable_name) != all_variable_maps_[type_index].end())
150  {
151  StdLargeVec<VariableType> *variable =
152  std::get<type_index>(all_particle_data_)[all_variable_maps_[type_index][variable_name]];
153  std::get<type_index>(sortable_data_).push_back(variable);
154  sortable_variable_maps_[type_index].insert(make_pair(variable_name, std::get<type_index>(sortable_data_).size() - 1));
155  }
156  else
157  {
158  std::cout << "\n Error: the variable '" << variable_name << "' for sorting is not registered!" << std::endl;
159  std::cout << __FILE__ << ':' << __LINE__ << std::endl;
160  exit(1);
161  }
162  }
163  else
164  {
165  std::cout << "\n Warning: the variable '" << variable_name << "' is already a sortable variable!" << std::endl;
166  std::cout << __FILE__ << ':' << __LINE__ << std::endl;
167  }
168  }
169  //=================================================================================================//
170  template <typename VariableType>
172  operator()(ParticleData &particle_data, size_t new_size) const
173  {
174  constexpr int type_index = DataTypeIndex<VariableType>::value;
175 
176  for (size_t i = 0; i != std::get<type_index>(particle_data).size(); ++i)
177  std::get<type_index>(particle_data)[i]->resize(new_size, VariableType(0));
178  }
179  //=================================================================================================//
180  template <typename VariableType>
181  void BaseParticles::addAParticleDataValue<VariableType>::
182  operator()(ParticleData &particle_data) const
183  {
184  constexpr int type_index = DataTypeIndex<VariableType>::value;
185 
186  for (size_t i = 0; i != std::get<type_index>(particle_data).size(); ++i)
187  std::get<type_index>(particle_data)[i]->push_back(VariableType(0));
188  }
189  //=================================================================================================//
190  template <typename VariableType>
191  void BaseParticles::copyAParticleDataValue<VariableType>::
192  operator()(ParticleData &particle_data, size_t this_index, size_t another_index) const
193  {
194  constexpr int type_index = DataTypeIndex<VariableType>::value;
195 
196  for (size_t i = 0; i != std::get<type_index>(particle_data).size(); ++i)
197  (*std::get<type_index>(particle_data)[i])[this_index] =
198  (*std::get<type_index>(particle_data)[i])[another_index];
199  }
200  //=================================================================================================//
201  template <typename StreamType>
202  void BaseParticles::writeParticlesToVtk(StreamType &output_stream)
203  {
204  size_t total_real_particles = total_real_particles_;
205 
206  // write current/final particle positions first
207  output_stream << " <Points>\n";
208  output_stream << " <DataArray Name=\"Position\" type=\"Float32\" NumberOfComponents=\"3\" Format=\"ascii\">\n";
209  output_stream << " ";
210  for (size_t i = 0; i != total_real_particles; ++i)
211  {
212  Vec3d particle_position = upgradeToVector3D(pos_[i]);
213  output_stream << particle_position[0] << " " << particle_position[1] << " " << particle_position[2] << " ";
214  }
215  output_stream << std::endl;
216  output_stream << " </DataArray>\n";
217  output_stream << " </Points>\n";
218 
219  // write header of particles data
220  output_stream << " <PointData Vectors=\"vector\">\n";
221 
222  // write sorted particles ID
223  output_stream << " <DataArray Name=\"SortedParticle_ID\" type=\"Int32\" Format=\"ascii\">\n";
224  output_stream << " ";
225  for (size_t i = 0; i != total_real_particles; ++i)
226  {
227  output_stream << i << " ";
228  }
229  output_stream << std::endl;
230  output_stream << " </DataArray>\n";
231 
232  // write unsorted particles ID
233  output_stream << " <DataArray Name=\"UnsortedParticle_ID\" type=\"Int32\" Format=\"ascii\">\n";
234  output_stream << " ";
235  for (size_t i = 0; i != total_real_particles; ++i)
236  {
237  output_stream << unsorted_id_[i] << " ";
238  }
239  output_stream << std::endl;
240  output_stream << " </DataArray>\n";
241 
242  // compute derived particle variables
243  for (ParticleDynamics<void> *derived_variable : derived_variables_)
244  {
245  derived_variable->parallel_exec();
246  }
247 
248  // write matrices
249  for (std::pair<std::string, size_t> &name_index : variables_to_write_[2])
250  {
251  std::string variable_name = name_index.first;
252  StdLargeVec<Matd> &variable = *(std::get<2>(all_particle_data_)[name_index.second]);
253  output_stream << " <DataArray Name=\"" << variable_name << "\" type=\"Float32\" NumberOfComponents=\"9\" Format=\"ascii\">\n";
254  output_stream << " ";
255  for (size_t i = 0; i != total_real_particles; ++i)
256  {
257  Mat3d matrix_value = upgradeToMatrix3D(variable[i]);
258  for (int k = 0; k != 3; ++k)
259  {
260  Vec3d col_vector = matrix_value.col(k);
261  output_stream << std::fixed << std::setprecision(9) << col_vector[0] << " " << col_vector[1] << " " << col_vector[2] << " ";
262  }
263  }
264  output_stream << std::endl;
265  output_stream << " </DataArray>\n";
266  }
267 
268  // write vectors
269  for (std::pair<std::string, size_t> &name_index : variables_to_write_[1])
270  {
271  std::string variable_name = name_index.first;
272  StdLargeVec<Vecd> &variable = *(std::get<1>(all_particle_data_)[name_index.second]);
273  output_stream << " <DataArray Name=\"" << variable_name << "\" type=\"Float32\" NumberOfComponents=\"3\" Format=\"ascii\">\n";
274  output_stream << " ";
275  for (size_t i = 0; i != total_real_particles; ++i)
276  {
277  Vec3d vector_value = upgradeToVector3D(variable[i]);
278  output_stream << std::fixed << std::setprecision(9) << vector_value[0] << " " << vector_value[1] << " " << vector_value[2] << " ";
279  }
280  output_stream << std::endl;
281  output_stream << " </DataArray>\n";
282  }
283 
284  // write scalars
285  for (std::pair<std::string, size_t> &name_index : variables_to_write_[0])
286  {
287  std::string variable_name = name_index.first;
288  StdLargeVec<Real> &variable = *(std::get<0>(all_particle_data_)[name_index.second]);
289  output_stream << " <DataArray Name=\"" << variable_name << "\" type=\"Float32\" Format=\"ascii\">\n";
290  output_stream << " ";
291  for (size_t i = 0; i != total_real_particles; ++i)
292  {
293  output_stream << std::fixed << std::setprecision(9) << variable[i] << " ";
294  }
295  output_stream << std::endl;
296  output_stream << " </DataArray>\n";
297  }
298 
299  // write integers
300  for (std::pair<std::string, size_t> &name_index : variables_to_write_[3])
301  {
302  std::string variable_name = name_index.first;
303  StdLargeVec<int> &variable = *(std::get<3>(all_particle_data_)[name_index.second]);
304  output_stream << " <DataArray Name=\"" << variable_name << "\" type=\"Int32\" Format=\"ascii\">\n";
305  output_stream << " ";
306  for (size_t i = 0; i != total_real_particles; ++i)
307  {
308  output_stream << std::fixed << std::setprecision(9) << variable[i] << " ";
309  }
310  output_stream << std::endl;
311  output_stream << " </DataArray>\n";
312  }
313  }
314  //=================================================================================================//
315  template <typename VariableType>
316  void WriteAParticleVariableToXml::
317  operator()(std::string &variable_name, StdLargeVec<VariableType> &variable) const
318  {
319  SimTK::Xml::element_iterator ele_ite = xml_engine_.root_element_.element_begin();
320  for (size_t i = 0; i != total_real_particles_; ++i)
321  {
322  xml_engine_.setAttributeToElement(ele_ite, variable_name, variable[i]);
323  ele_ite++;
324  }
325  }
326  //=================================================================================================//
327  template <typename VariableType>
328  void ReadAParticleVariableFromXml::
329  operator()(std::string &variable_name, StdLargeVec<VariableType> &variable) const
330  {
331  SimTK::Xml::element_iterator ele_ite = xml_engine_.root_element_.element_begin();
332  for (size_t i = 0; i != total_real_particles_; ++i)
333  {
334  xml_engine_.getRequiredAttributeValue(ele_ite, variable_name, variable[i]);
335  ele_ite++;
336  }
337  }
338  //=================================================================================================//
339  template <typename VariableType>
340  BaseDerivedVariable<VariableType>::
341  BaseDerivedVariable(const SPHBody &sph_body, const std::string &variable_name)
342  : variable_name_(variable_name)
343  {
344  sph_body.base_particles_->registerVariable(derived_variable_, variable_name_);
345  };
346  //=================================================================================================//
347 }
348 #endif // BASE_PARTICLES_HPP
Definition: base_particles.h:216
void getRequiredAttributeValue(SimTK::Xml::element_iterator &ele_ite_, const std::string &attrib_name, T &value)
Definition: xml_engine.h:88
std::array< StdVec< std::pair< std::string, size_t > >, 4 > ParticleVariableList
Definition: sph_data_containers.h:63
GeneralDataAssemble< StdLargeVec > ParticleData
Definition: sph_data_containers.h:59
void registerSortableVariable(const std::string &variable_name)
Definition: base_particles.hpp:143
SimTK::Xml::Element root_element_
Definition: xml_engine.h:66
void addVariableToRestart(const std::string &variable_name)
Definition: base_particles.hpp:131
Definition: particle_dynamics_algorithms.h:247
void addVariableToReload(const std::string &variable_name)
Definition: base_particles.hpp:137
StdLargeVec< VariableType > * getVariableByName(const std::string &variable_name)
Definition: base_particles.hpp:74
void addVariableToWrite(const std::string &variable_name)
Definition: base_particles.hpp:116
void registerVariable(StdLargeVec< VariableType > &variable_addrs, const std::string &variable_name, VariableType initial_value=VariableType(0))
Definition: base_particles.hpp:40
void addDerivedVariableToWrite()
Definition: base_particles.hpp:122
void setAttributeToElement(const SimTK::Xml::element_iterator &ele_ite, const std::string &attrib_name, const T &value)
Definition: xml_engine.h:78
void addVariableNameToList(ParticleVariableList &variable_name_list, const std::string &variable_name)
Definition: base_particles.hpp:89
This is the base class of SPH particles. The basic data of the particles is saved in separated large ...
void writeParticlesToVtk(OutStreamType &output_stream)
This is the classes for algorithms particle dynamics. Generally, there are four types dynamics...
size_t real_particles_bound_
Definition: base_particles.h:109
Definition: base_data_type.h:320
StdLargeVec< size_t > unsorted_id_
Definition: base_particles.h:156
StdLargeVec< Vecd > pos_
Definition: base_particles.h:88
Definition: solid_body_supplementary.cpp:9