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.
atomic_utilities.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Riccardo Rossi
11 // Denis Demidov
12 // Philipp Bucher (https://github.com/philbucher)
13 //
14 
15 #pragma once
16 
17 // System includes
18 #include <atomic>
19 
20 // External includes
21 #ifdef KRATOS_SMP_OPENMP
22 #include <omp.h>
23 #endif
24 
25 #if !defined(__cpp_lib_atomic_ref) && defined(KRATOS_SMP_CXX11)
26 #include <boost/atomic/atomic_ref.hpp>
27 #endif
28 
29 // Project includes
30 #include "includes/define.h"
31 #include "containers/array_1d.h"
32 
33 namespace Kratos {
34 
35 #if defined(KRATOS_SMP_CXX11)
36  #if defined(__cpp_lib_atomic_ref) // C++20
37  template <class T>
38  using AtomicRef = std::atomic_ref<T>;
39  #else
40  template <class T>
41  using AtomicRef = boost::atomic_ref<T>;
42  #endif //__cpp_lib_atomic_ref
43 #endif // KRATOS_SMP_CXX11
44 
46 
54 template<class TDataType>
55 inline void AtomicAdd(TDataType& target, const TDataType& value)
56 {
57 #ifdef KRATOS_SMP_OPENMP
58  #pragma omp atomic
59  target += value;
60 #elif defined(KRATOS_SMP_CXX11)
61  AtomicRef<TDataType>{target} += value;
62 #else
63  target += value;
64 #endif
65 }
66 
73 template <class TDataType, std::size_t ArraySize>
75 {
76  for (std::size_t i=0; i<ArraySize; ++i) {
77  AtomicAdd(target[i], value[i]);
78  }
79 }
80 
86 template<class TVectorType1, class TVectorType2>
87 inline void AtomicAddVector(TVectorType1& target, const TVectorType2& value)
88 {
89  KRATOS_DEBUG_ERROR_IF(target.size() != value.size()) << "vector size mismatch in vector AtomicAddVector- Sizes are: " << target.size() << " for target and " << value.size() << " for value " << std::endl;
90 
91  for(std::size_t i=0; i<target.size(); ++i) {
92  AtomicAdd(target[i], value[i]);
93  }
94 }
95 
101 template<class TMatrixType1, class TMatrixType2>
102 inline void AtomicAddMatrix(TMatrixType1& target, const TMatrixType2& value)
103 {
104  KRATOS_DEBUG_ERROR_IF(target.size1() != value.size1() || target.size2() != value.size2()) << "matrix size mismatch in matrix AtomicAddMatrix- Sizes are: " << target.size1() << "x" << target.size2() << " for target and " << value.size1() << "x" << value.size2() << " for value " << std::endl;
105 
106  for(std::size_t i=0; i<target.size1(); ++i) {
107  for(std::size_t j=0; j<target.size2(); ++j) {
108  AtomicAdd(target(i,j), value(i,j));
109  }
110  }
111 }
112 
117 template<class TDataType>
118 inline void AtomicSub(TDataType& target, const TDataType& value)
119 {
120 #ifdef KRATOS_SMP_OPENMP
121  #pragma omp atomic
122  target -= value;
123 #elif defined(KRATOS_SMP_CXX11)
124  AtomicRef<TDataType>{target} -= value;
125 #else
126  target -= value;
127 #endif
128 }
129 
136 template <class TDataType, std::size_t ArraySize>
138 {
139  for(std::size_t i=0; i<ArraySize; ++i) {
140  AtomicSub(target[i], value[i]);
141  }
142 }
143 
149 template<class TVectorType1, class TVectorType2>
150 inline void AtomicSubVector(TVectorType1& target, const TVectorType2& value) {
151  KRATOS_DEBUG_ERROR_IF(target.size() != value.size()) << "vector size mismatch in vector AtomicSubVector- Sizes are: " << target.size() << " for target and " << value.size() << " for value " << std::endl;
152 
153  for(std::size_t i=0; i<target.size(); ++i) {
154  AtomicSub(target[i], value[i]);
155  }
156 }
157 
163 template<class TMatrixType1, class TMatrixType2>
164 inline void AtomicSubMatrix(TMatrixType1& target, const TMatrixType2& value)
165 {
166  KRATOS_DEBUG_ERROR_IF(target.size1() != value.size1() || target.size2() != value.size2()) << "matrix size mismatch in matrix AtomicSubMatrix- Sizes are: " << target.size1() << "x" << target.size2() << " for target and " << value.size1() << "x" << value.size2() << " for value " << std::endl;
167 
168  for(std::size_t i=0; i<target.size1(); ++i) {
169  for(std::size_t j=0; j<target.size2(); ++j) {
170  AtomicSub(target(i,j), value(i,j));
171  }
172  }
173 }
174 
178 template<class TDataType>
179 inline void AtomicMult(TDataType& target, const TDataType& value)
180 {
181 #ifdef KRATOS_SMP_OPENMP
182  #pragma omp atomic
183  target *= value;
184 #elif defined(KRATOS_SMP_CXX11)
185  AtomicRef<TDataType> at_ref{target};
186  at_ref = at_ref*value;
187 #else
188  target *= value;
189 #endif
190 }
191 
197 template <class TDataType, std::size_t ArraySize>
199 {
200  for(std::size_t i=0; i<ArraySize; ++i) {
201  AtomicMult(target[i], value[i]);
202  }
203 }
204 
209 template<class TVectorType1, class TVectorType2>
210 inline void AtomicMultVector(TVectorType1& target, const TVectorType2& value)
211 {
212  KRATOS_DEBUG_ERROR_IF(target.size() != value.size()) << "vector size mismatch in vector AtomicMultVector- Sizes are: " << target.size() << " for target and " << value.size() << " for value " << std::endl;
213 
214  for(std::size_t i=0; i<target.size(); ++i) {
215  AtomicMult(target[i], value[i]);
216  }
217 }
218 
224 template<class TMatrixType1, class TMatrixType2>
225 inline void AtomicMultMatrix(TMatrixType1& target, const TMatrixType2& value)
226 {
227  KRATOS_DEBUG_ERROR_IF(target.size1() != value.size1() || target.size2() != value.size2()) << "matrix size mismatch in matrix AtomicMultMatrix- Sizes are: " << target.size1() << "x" << target.size2() << " for target and " << value.size1() << "x" << value.size2() << " for value " << std::endl;
228 
229  for(std::size_t i=0; i<target.size1(); ++i) {
230  for(std::size_t j=0; j<target.size2(); ++j) {
231  AtomicMult(target(i,j), value(i,j));
232  }
233  }
234 }
235 
239 template<class TDataType>
240 inline void AtomicDiv(TDataType& target, const TDataType& value)
241 {
242  AtomicMult(target, 1.0/value);
243 }
244 
250 template <class TDataType, std::size_t ArraySize>
252 {
253  for(std::size_t i=0; i<ArraySize; ++i) {
254  AtomicDiv(target[i], value[i]);
255  }
256 }
257 
262 template<class TVectorType1, class TVectorType2>
263 inline void AtomicDivVector(TVectorType1& target, const TVectorType2& value)
264 {
265  KRATOS_DEBUG_ERROR_IF(target.size() != value.size()) << "vector size mismatch in vector AtomicDivVector- Sizes are: " << target.size() << " for target and " << value.size() << " for value " << std::endl;
266 
267  for(std::size_t i=0; i<target.size(); ++i) {
268  AtomicDiv(target[i], value[i]);
269  }
270 }
271 
277 template<class TMatrixType1, class TMatrixType2>
278 inline void AtomicDivMatrix(TMatrixType1& target, const TMatrixType2& value)
279 {
280  KRATOS_DEBUG_ERROR_IF(target.size1() != value.size1() || target.size2() != value.size2()) << "matrix size mismatch in matrix AtomicDivMatrix- Sizes are: " << target.size1() << "x" << target.size2() << " for target and " << value.size1() << "x" << value.size2() << " for value " << std::endl;
281 
282  for(std::size_t i=0; i<target.size1(); ++i) {
283  for(std::size_t j=0; j<target.size2(); ++j) {
284  AtomicDiv(target(i,j), value(i,j));
285  }
286  }
287 }
288 
289 } // namespace Kratos.
Short class definition.
Definition: array_1d.h:61
#define KRATOS_DEBUG_ERROR_IF(conditional)
Definition: exception.h:171
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
void AtomicAdd(TDataType &target, const TDataType &value)
Definition: atomic_utilities.h:55
void AtomicAddVector(TVectorType1 &target, const TVectorType2 &value)
Definition: atomic_utilities.h:87
void AtomicDivVector(TVectorType1 &target, const TVectorType2 &value)
Definition: atomic_utilities.h:263
void AtomicDiv(TDataType &target, const TDataType &value)
Definition: atomic_utilities.h:240
void AtomicSubVector(TVectorType1 &target, const TVectorType2 &value)
Definition: atomic_utilities.h:150
void AtomicSubMatrix(TMatrixType1 &target, const TMatrixType2 &value)
Definition: atomic_utilities.h:164
void AtomicMultVector(TVectorType1 &target, const TVectorType2 &value)
Definition: atomic_utilities.h:210
void AtomicMultMatrix(TMatrixType1 &target, const TMatrixType2 &value)
Definition: atomic_utilities.h:225
void AtomicDivMatrix(TMatrixType1 &target, const TMatrixType2 &value)
Definition: atomic_utilities.h:278
void AtomicAddMatrix(TMatrixType1 &target, const TMatrixType2 &value)
Definition: atomic_utilities.h:102
void AtomicSub(TDataType &target, const TDataType &value)
Definition: atomic_utilities.h:118
void AtomicMult(TDataType &target, const TDataType &value)
Definition: atomic_utilities.h:179
int j
Definition: quadrature.py:648
integer i
Definition: TensorModule.f:17