KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
variables_list.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 
6 // Multi-Physics
7 //
8 // License: BSD License
9 // Kratos default license: kratos/license.txt
10 //
11 // Main authors: Pooyan Dadvand
12 //
13 //
14 
15 #if !defined(KRATOS_VARIABLES_LIST_H_INCLUDED )
16 #define KRATOS_VARIABLES_LIST_H_INCLUDED
17 
18 
19 
20 // System includes
21 #include <string>
22 #include <iostream>
23 #include <vector>
24 #include <atomic>
25 
26 // External includes
27 #include <boost/iterator/indirect_iterator.hpp>
28 
29 
30 // Project includes
31 #include "includes/define.h"
32 #include "containers/variable.h"
33 
34 #ifdef KRATOS_DEBUG
35 #include "utilities/openmp_utils.h"
36 #endif
37 
38 
39 namespace Kratos
40 {
41 
44 
46 
49  class KRATOS_API(KRATOS_CORE) VariablesList final
50  {
51  public:
54 
57 
58 
59 
60  typedef std::size_t SizeType;
61 
62  typedef std::size_t IndexType;
63 
64  typedef double BlockType;
65 
66  typedef std::vector<IndexType> KeysContainerType;
67 
68  typedef std::vector<IndexType> PositionsContainerType;
69 
70  typedef std::vector<const VariableData*> VariablesContainerType;
71 
73  typedef const VariableData* value_type;
74  typedef const VariableData* const_pointer;
75  typedef VariableData const& const_reference;
76 
77  typedef boost::indirect_iterator<VariablesContainerType::const_iterator> const_iterator;
78  typedef boost::indirect_iterator<VariablesContainerType::const_reverse_iterator> const_reverse_iterator;
79 
80  typedef VariablesContainerType::size_type size_type;
81  typedef VariablesContainerType::const_iterator ptr_const_iterator;
82  typedef VariablesContainerType::const_reverse_iterator ptr_const_reverse_iterator;
83  typedef VariablesContainerType::difference_type difference_type;
84 
85 
89 
92  {}
93 
94  template <class TInputIteratorType>
95  VariablesList(TInputIteratorType First, TInputIteratorType Last)
96  {
97  for (; First != Last; First++)
98  Add(*First);
99  }
100 
102  VariablesList(VariablesList const& rOther) : mDataSize(rOther.mDataSize)
103  , mHashFunctionIndex(rOther.mHashFunctionIndex)
104  , mKeys(rOther.mKeys)
105  , mPositions(rOther.mPositions)
106  , mVariables(rOther.mVariables)
107  , mDofVariables(rOther.mDofVariables)
108  , mDofReactions(rOther.mDofReactions)
109  {}
110 
113  {
114  }
115 
116 
120 
123  {
124  mDataSize = rOther.mDataSize;
125  mHashFunctionIndex = rOther.mHashFunctionIndex;
126  mKeys = rOther.mKeys;
127  mPositions = rOther.mPositions;
128  mVariables = rOther.mVariables;
129  mDofVariables=rOther.mDofVariables;
130  mDofReactions=rOther.mDofReactions;
131 
132  return *this;
133  }
134 
135  IndexType operator()(IndexType VariableKey) const
136  {
137  return GetPosition(VariableKey);
138  }
139 
140  template<class TDataType>
141  IndexType operator()(Variable<TDataType> const& ThisVariable) const
142  {
143  return GetPosition(ThisVariable.SourceKey());
144  }
145 
147  {
148  return mVariables[Index];
149  }
150 
151 
152  bool operator==(const VariablesList& r) const // nothrow
153  {
154  if (size() != r.size())
155  return false;
156  else
157  return std::equal(mPositions.begin(), mPositions.end(), r.mPositions.begin()) &&
158  std::equal(mVariables.begin(), mVariables.end(), r.mVariables.begin());
159  }
160 
161  //public API of intrusive_ptr
162  unsigned int use_count() const noexcept
163  {
164  return mReferenceCounter;
165  }
169 
171  {
172  return const_iterator(mVariables.begin());
173  }
175  {
176  return const_iterator(mVariables.end());
177  }
179  {
180  return const_reverse_iterator(mVariables.rbegin());
181  }
183  {
184  return const_reverse_iterator(mVariables.rend());
185  }
187  {
188  return mVariables.begin();
189  }
191  {
192  return mVariables.end();
193  }
195  {
196  return mVariables.rbegin();
197  }
199  {
200  return mVariables.rend();
201  }
202 
203  const_reference front() const /* nothrow */
204  {
205  assert(!IsEmpty());
206  return *mVariables.front();
207  }
208  const_reference back() const /* nothrow */
209  {
210  assert(!IsEmpty());
211  return *mVariables.back();
212  }
213 
214  size_type size() const
215  {
216  return mVariables.size();
217  }
218 
220  {
221  return mVariables.max_size();
222  }
223 
224  void swap(VariablesList& rOther)
225  {
226  SizeType temp = mDataSize;
227  mDataSize = rOther.mDataSize;
228  rOther.mDataSize = temp;
229 
230  temp = mHashFunctionIndex;
231  mHashFunctionIndex = rOther.mHashFunctionIndex;
232  rOther.mHashFunctionIndex = temp;
233 
234  mVariables.swap(rOther.mVariables);
235 
236  mDofVariables.swap(rOther.mDofVariables);
237  mDofReactions.swap(rOther.mDofReactions);
238 
239  mKeys.swap(rOther.mKeys);
240  mPositions.swap(rOther.mPositions);
241  }
242 
243  template<class TOtherDataType>
244  void push_back(TOtherDataType const& x)
245  {
246  Add(x);
247  }
248 
249  void clear()
250  {
251  mDataSize = 0;
252  mHashFunctionIndex = 0;
253  mVariables.clear();
254  mDofVariables.clear();
255  mDofReactions.clear();
256  mKeys = {static_cast<IndexType>(-1)};
257  mPositions = {static_cast<IndexType>(-1)};
258  }
259 
260 
261  void Add(VariableData const& ThisVariable)
262  {
263  if (ThisVariable.SourceKey() == 0)
264  KRATOS_THROW_ERROR(std::logic_error,
265  "Adding uninitialize variable to this variable list. Check if all variables are registered before kernel initialization", "");
266 
267 
268  if (Has(ThisVariable))
269  return;
270 
271  if(ThisVariable.IsComponent()){
272  Add(ThisVariable.GetSourceVariable());
273  return;
274  }
275 
276  mVariables.push_back(&ThisVariable);
277  SetPosition(ThisVariable.SourceKey(), mDataSize);
278  const SizeType block_size = sizeof(BlockType);
279  mDataSize += static_cast<SizeType>(((block_size - 1) + ThisVariable.Size()) / block_size);
280  }
281 
282  int AddDof(VariableData const* pThisDofVariable){
283 
284  for(std::size_t dof_index = 0 ; dof_index < mDofVariables.size() ; dof_index++){
285  if(*mDofVariables[dof_index] == *pThisDofVariable){
286  return static_cast<int>(dof_index);
287  }
288  }
289 
290 #ifdef KRATOS_DEBUG
291  if(OpenMPUtils::IsInParallel() != 0)
292  KRATOS_ERROR << "attempting to call AddDof for: " << pThisDofVariable << ". Unfortunately the Dof was not added before and the operations is not threadsafe (this function is being called within a parallel region)" << std::endl;
293 #endif
294  mDofVariables.push_back(pThisDofVariable);
295  mDofReactions.push_back(nullptr);
296 
297  KRATOS_DEBUG_ERROR_IF(mDofVariables.size()>64) << "Adding too many dofs to the node. Each node only can store 64 Dofs." << std::endl;
298 
299  return mDofVariables.size() - 1;
300  }
301 
302  int AddDof(VariableData const* pThisDofVariable, VariableData const* pThisDofReaction){
303 
304  for(std::size_t dof_index = 0 ; dof_index < mDofVariables.size() ; dof_index++){
305  if(*mDofVariables[dof_index] == *pThisDofVariable){
306  mDofReactions[dof_index] = pThisDofReaction;
307  return static_cast<int>(dof_index);
308  }
309  }
310 
311 #ifdef KRATOS_DEBUG
312  if(OpenMPUtils::IsInParallel() != 0)
313  KRATOS_ERROR << "attempting to call AddDof for: " << pThisDofVariable << ". Unfortunately the Dof was not added before and the operations is not threadsafe (this function is being called within a parallel region)" << std::endl;
314 #endif
315  mDofVariables.push_back(pThisDofVariable);
316  mDofReactions.push_back(pThisDofReaction);
317 
318  KRATOS_DEBUG_ERROR_IF(mDofVariables.size()>64) << "Adding too many dofs to the node. Each node only can store 64 Dofs." << std::endl;
319 
320  return mDofVariables.size() - 1;
321  }
322 
323  const VariableData& GetDofVariable(int DofIndex) const {
324  return *mDofVariables[DofIndex];
325  }
326 
327  const VariableData* pGetDofReaction(int DofIndex) const {
328  return mDofReactions[DofIndex];
329  }
330 
331  void SetDofReaction(VariableData const* pThisDofReaction, int DofIndex) {
332  KRATOS_DEBUG_ERROR_IF(static_cast<std::size_t>(DofIndex) >= mDofReactions.size()) << "The given dof with index = " << DofIndex << " is not stored in this variables list" << std::endl;
333  mDofReactions[DofIndex] = pThisDofReaction;
334  }
335 
336  IndexType Index(IndexType VariableKey) const
337  {
338  return GetPosition(VariableKey);
339  }
340 
341  template<class TDataType>
342  IndexType Index(Variable<TDataType> const& ThisVariable) const
343  {
344  return GetPosition(ThisVariable.SourceKey());
345  }
346 
347  IndexType Index(const VariableData* pThisVariable) const
348  {
349  return GetPosition(pThisVariable->SourceKey());
350  }
351 
352 
356 
358  {
359  return mDataSize;
360  }
361 
362 
364  {
365  return mVariables;
366  }
367 
371 
372  bool Has(const VariableData& rThisVariable) const
373  {
374  if(rThisVariable.IsComponent()){
375  return Has(rThisVariable.GetSourceVariable());
376  }
377 
378  if (mPositions.empty())
379  return false;
380 
381  if (rThisVariable.SourceKey() == 0)
382  return false;
383 
384  return mKeys[GetHashIndex(rThisVariable.SourceKey(), mKeys.size(), mHashFunctionIndex)] == rThisVariable.SourceKey();
385  }
386 
387  bool IsEmpty() const
388  {
389  return mVariables.empty();
390  }
391 
395 
397  std::string Info() const
398  {
399  return "variables list";
400  }
401 
403  void PrintInfo(std::ostream& rOStream) const
404  {
405  rOStream << Info();
406  }
407 
409  void PrintData(std::ostream& rOStream) const
410  {
411  rOStream << " with " << size() << " variables";
412  rOStream << " (size : " << mDataSize << " blocks of " << sizeof(BlockType) << " bytes) " << std::endl;
413  for (IndexType i = 0; i < mVariables.size(); ++i)
414  rOStream << " " << mVariables[i]->Name() << " \t-> " << GetPosition(mVariables[i]->Key()) << std::endl;
415 
416  rOStream << " with " << mDofVariables.size() << " Dofs:";
417  for (IndexType i = 0; i < mDofVariables.size(); ++i)
418  rOStream << " [" << mDofVariables[i]->Name() << " , " << ((mDofReactions[i] == nullptr) ? "NONE" : mDofReactions[i]->Name()) << "]" << std::endl;
419  }
420 
421 
423  private:
426  SizeType mDataSize = 0;
427 
428  SizeType mHashFunctionIndex = 0;
429 
430  KeysContainerType mKeys = {static_cast<IndexType>(-1)};
431 
432  PositionsContainerType mPositions = {static_cast<IndexType>(-1)};
433 
434  VariablesContainerType mVariables;
435 
436  VariablesContainerType mDofVariables;
437 
438  VariablesContainerType mDofReactions;
439 
443  //this block is needed for refcounting
444  mutable std::atomic<int> mReferenceCounter{0};
445 
447  {
448  x->mReferenceCounter.fetch_add(1, std::memory_order_relaxed);
449  }
450 
452  {
453  if (x->mReferenceCounter.fetch_sub(1, std::memory_order_release) == 1) {
454  std::atomic_thread_fence(std::memory_order_acquire);
455  delete x;
456  }
457  }
458 
462 
463 
464  void SetPosition(IndexType Key, SizeType ThePosition) {
465  if (mPositions.empty())
466  ResizePositions();
467 
468  if (mPositions[GetHashIndex(Key,mPositions.size(),mHashFunctionIndex)] < mDataSize) // The position is ocupied and a resize (as re hash) is needed
469  ResizePositions();
470 
471  mKeys[GetHashIndex(Key, mPositions.size(), mHashFunctionIndex)] = Key;
472  mPositions[GetHashIndex(Key, mPositions.size(), mHashFunctionIndex)] = ThePosition;
473  }
474 
475  SizeType GetHashIndex(std::size_t Key, std::size_t TableSize, std::size_t HashFunctionIndex) const{
476  return (Key >> HashFunctionIndex) & (TableSize - 1);
477  }
478 
479  SizeType GetPosition(IndexType Key) const {
480  SizeType index = GetHashIndex(Key,mPositions.size(),mHashFunctionIndex);
481  return mPositions[index];
482  }
483 
484  void ResizePositions() {
485  bool size_is_ok = false;
486  std::size_t new_size = mPositions.size();
487  SizeType new_hash_function_index = 0;
488  while (size_is_ok != true) {
489  new_hash_function_index++;
490  if (new_hash_function_index > 31) {
491  new_hash_function_index = 0;
492  new_size *= 2;
493  }
494  KeysContainerType new_keys(new_size, static_cast<IndexType>(-1));
495  PositionsContainerType new_positions(new_size, static_cast<IndexType>(-1));
496  size_is_ok = true;
497 
498  for (auto i_variable = mVariables.begin(); i_variable != mVariables.end(); i_variable++)
499  if (new_positions[GetHashIndex((*i_variable)->SourceKey(), new_size, new_hash_function_index)] > mDataSize) {
500  new_positions[GetHashIndex((*i_variable)->SourceKey(), new_size, new_hash_function_index)] = mPositions[GetHashIndex((*i_variable)->SourceKey(), mPositions.size(), mHashFunctionIndex)];
501  new_keys[GetHashIndex((*i_variable)->SourceKey(), new_size, new_hash_function_index)] = (*i_variable)->SourceKey();
502  }
503  else {
504  size_is_ok = false;
505  break;
506  }
507 
508  if (size_is_ok) {
509  mPositions.swap(new_positions);
510  mKeys.swap(new_keys);
511  mHashFunctionIndex = new_hash_function_index;
512  }
513  }
514  }
515 
519 
520  friend class Serializer;
521 
522 
523  virtual void save(Serializer& rSerializer) const;
524 
525  virtual void load(Serializer& rSerializer);
526 
527  }; // Class VariablesList
531 
532 
534  inline std::istream& operator >> (std::istream& rIStream,
535  VariablesList& rThis);
536 
538  inline std::ostream& operator << (std::ostream& rOStream,
539  const VariablesList& rThis)
540  {
541  rThis.PrintInfo(rOStream);
542  rThis.PrintData(rOStream);
543 
544  return rOStream;
545  }
547 
548 
549 } // namespace Kratos.
550 
551 #endif // KRATOS_VARIABLES_LIST_H_INCLUDED defined
std::string Info() const override
Turn back information as a string.
Definition: periodic_interface_process.hpp:93
static int IsInParallel()
Wrapper for omp_in_parallel().
Definition: openmp_utils.h:122
The serialization consists in storing the state of an object into a storage format like data file or ...
Definition: serializer.h:123
This class is the base of variables and variable's components which contains their common data.
Definition: variable_data.h:49
KeyType SourceKey() const
Definition: variable_data.h:192
std::size_t Size() const
Definition: variable_data.h:206
const VariableData & GetSourceVariable() const
Definition: variable_data.h:232
bool IsComponent() const
Definition: variable_data.h:211
Variable class contains all information needed to store and retrive data from a data container.
Definition: variable.h:63
Holds a list of variables and their position in VariablesListDataValueContainer.
Definition: variables_list.h:50
VariablesList(VariablesList const &rOther)
Copy constructor.
Definition: variables_list.h:102
ptr_const_iterator ptr_end() const
Definition: variables_list.h:190
VariablesContainerType::const_reverse_iterator ptr_const_reverse_iterator
Definition: variables_list.h:82
std::vector< IndexType > KeysContainerType
Definition: variables_list.h:66
VariableData data_type
Definition: variables_list.h:72
void SetDofReaction(VariableData const *pThisDofReaction, int DofIndex)
Definition: variables_list.h:331
KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(VariablesList)
Pointer definition of VariablesList.
VariablesList & operator=(VariablesList const &rOther)
Assignment operator.
Definition: variables_list.h:122
const_iterator end() const
Definition: variables_list.h:174
VariablesList()
Default constructor. mPosition should have at least on entry.
Definition: variables_list.h:91
std::vector< const VariableData * > VariablesContainerType
Definition: variables_list.h:70
const VariableData * value_type
Definition: variables_list.h:73
~VariablesList()
Destructor.
Definition: variables_list.h:112
std::size_t SizeType
Definition: variables_list.h:60
const VariableData * pGetDofReaction(int DofIndex) const
Definition: variables_list.h:327
VariablesContainerType::const_iterator ptr_const_iterator
Definition: variables_list.h:81
void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: variables_list.h:403
IndexType operator()(Variable< TDataType > const &ThisVariable) const
Definition: variables_list.h:141
size_type size() const
Definition: variables_list.h:214
VariablesContainerType const & Variables()
Definition: variables_list.h:363
int AddDof(VariableData const *pThisDofVariable)
Definition: variables_list.h:282
void push_back(TOtherDataType const &x)
Definition: variables_list.h:244
const_reference front() const
Definition: variables_list.h:203
friend void intrusive_ptr_add_ref(const VariablesList *x)
Definition: variables_list.h:446
boost::indirect_iterator< VariablesContainerType::const_reverse_iterator > const_reverse_iterator
Definition: variables_list.h:78
VariablesContainerType::difference_type difference_type
Definition: variables_list.h:83
ptr_const_reverse_iterator ptr_rend() const
Definition: variables_list.h:198
ptr_const_iterator ptr_begin() const
Definition: variables_list.h:186
IndexType Index(const VariableData *pThisVariable) const
Definition: variables_list.h:347
IndexType Index(Variable< TDataType > const &ThisVariable) const
Definition: variables_list.h:342
void clear()
Definition: variables_list.h:249
double BlockType
Definition: variables_list.h:64
const_reverse_iterator rend() const
Definition: variables_list.h:182
VariablesContainerType::size_type size_type
Definition: variables_list.h:80
VariablesList(TInputIteratorType First, TInputIteratorType Last)
Definition: variables_list.h:95
size_type max_size() const
Definition: variables_list.h:219
const_reference back() const
Definition: variables_list.h:208
IndexType Index(IndexType VariableKey) const
Definition: variables_list.h:336
std::string Info() const
Turn back information as a string.
Definition: variables_list.h:397
bool operator==(const VariablesList &r) const
Definition: variables_list.h:152
IndexType operator()(IndexType VariableKey) const
Definition: variables_list.h:135
friend void intrusive_ptr_release(const VariablesList *x)
Definition: variables_list.h:451
bool IsEmpty() const
Definition: variables_list.h:387
void swap(VariablesList &rOther)
Definition: variables_list.h:224
unsigned int use_count() const noexcept
Definition: variables_list.h:162
const VariableData * const_pointer
Definition: variables_list.h:74
std::size_t IndexType
Definition: variables_list.h:62
std::vector< IndexType > PositionsContainerType
Definition: variables_list.h:68
int AddDof(VariableData const *pThisDofVariable, VariableData const *pThisDofReaction)
Definition: variables_list.h:302
const VariableData & GetDofVariable(int DofIndex) const
Definition: variables_list.h:323
void Add(VariableData const &ThisVariable)
Definition: variables_list.h:261
const VariableData * operator[](IndexType Index) const
Definition: variables_list.h:146
VariableData const & const_reference
Definition: variables_list.h:75
bool Has(const VariableData &rThisVariable) const
Definition: variables_list.h:372
boost::indirect_iterator< VariablesContainerType::const_iterator > const_iterator
Definition: variables_list.h:77
ptr_const_reverse_iterator ptr_rbegin() const
Definition: variables_list.h:194
SizeType DataSize() const
Definition: variables_list.h:357
const_iterator begin() const
Definition: variables_list.h:170
const_reverse_iterator rbegin() const
Definition: variables_list.h:178
void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: variables_list.h:409
#define KRATOS_THROW_ERROR(ExceptionType, ErrorMessage, MoreInfo)
Definition: define.h:77
std::size_t IndexType
The definition of the index type.
Definition: key_hash.h:35
#define KRATOS_ERROR
Definition: exception.h:161
#define KRATOS_DEBUG_ERROR_IF(conditional)
Definition: exception.h:171
bool Has(const std::string &ModelerName)
Checks if the modeler is registered.
Definition: modeler_factory.cpp:24
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
std::size_t SizeType
The definition of the size type.
Definition: mortar_classes.h:43
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
int block_size
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:16
def Index()
Definition: hdf5_io_tools.py:38
def load(f)
Definition: ode_solve.py:307
tuple const
Definition: ode_solve.py:403
float temp
Definition: rotating_cone.py:85
x
Definition: sensitivityMatrix.py:49
integer i
Definition: TensorModule.f:17
def IsEmpty(_A)
Definition: custom_math.py:33