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.
ublas_space.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 // Collaborator: Vicente Mataix Ferrandiz
12 //
13 
14 #pragma once
15 
16 // System includes
17 #include <numeric>
18 
19 // External includes
20 
21 // Project includes
22 #include "includes/define.h"
23 #include "includes/process_info.h"
26 #include "utilities/dof_updater.h"
29 
30 namespace Kratos
31 {
32 #ifdef _OPENMP
33 // The function object multiplies an element by a Factor
34 
35 template <class Type>
36 class MultValueNoAdd
37 {
38 private:
39  Type Factor; // The value to multiply by
40 public:
41  // Constructor initializes the value to multiply by
42 
43  MultValueNoAdd(const Type& _Val) : Factor(_Val)
44  {
45  }
46 
47  // The function call for the element to be multiplied
48 
49  inline Type operator () (const Type& elem) const
50  {
51  return elem * Factor;
52  }
53 };
54 
55 template <class Type>
56 class MultAndAddValue
57 {
58 private:
59  Type Factor; // The value to multiply by
60 public:
61  // Constructor initializes the value to multiply by
62 
63  MultAndAddValue(const Type& _Val) : Factor(_Val)
64  {
65  }
66 
67  // The function call for the element to be multiplied
68 
69  inline Type operator () (const Type& elem1, const Type& elem2) const
70  {
71  return elem1 * Factor + elem2;
72  }
73 };
74 #endif
75 
78 
82 
83 template <class TDataType, class TMatrixType, class TVectorType>
84 class UblasSpace;
85 
86 template <class TDataType>
88  UblasSpace<TDataType, boost::numeric::ublas::compressed_matrix<TDataType>, boost::numeric::ublas::vector<TDataType>>;
89 template <class TDataType>
92 
96 
97 // Scaling enum
99 
103 
107 
119 template<class TDataType, class TMatrixType, class TVectorType>
121 {
122 public:
125 
128 
130  using DataType = TDataType;
131 
133  using MatrixType = TMatrixType;
134 
136  using VectorType = TVectorType;
137 
139  using IndexType = std::size_t;
140 
142  using SizeType = std::size_t;
143 
146 
149 
152 
154  using DofUpdaterPointerType = typename DofUpdaterType::UniquePointer;
155 
159 
162  {
163  }
164 
166  virtual ~UblasSpace()
167  {
168  }
169 
173 
177 
179  {
180  return MatrixPointerType(new TMatrixType(0, 0));
181  }
182 
184  {
185  return VectorPointerType(new TVectorType(0));
186  }
187 
189 
190  static IndexType Size(VectorType const& rV)
191  {
192  return rV.size();
193  }
194 
196 
197  static IndexType Size1(MatrixType const& rM)
198  {
199  return rM.size1();
200  }
201 
203 
204  static IndexType Size2(MatrixType const& rM)
205  {
206  return rM.size2();
207  }
208 
210  // This version is needed in order to take one column of multi column solve from AMatrix matrix and pass it to an ublas vector
211  template<typename TColumnType>
212  static void GetColumn(unsigned int j, Matrix& rM, TColumnType& rX)
213  {
214  if (rX.size() != rM.size1())
215  rX.resize(rM.size1(), false);
216 
217  for (std::size_t i = 0; i < rM.size1(); i++) {
218  rX[i] = rM(i, j);
219  }
220  }
221 
222  // This version is needed in order to take one column of multi column solve from AMatrix matrix and pass it to an ublas vector
223  template<typename TColumnType>
224  static void SetColumn(unsigned int j, Matrix& rM, TColumnType& rX)
225  {
226  for (std::size_t i = 0; i < rM.size1(); i++) {
227  rM(i,j) = rX[i];
228  }
229  }
230 
231 
233 
234  static void Copy(MatrixType const& rX, MatrixType& rY)
235  {
236  rY.assign(rX);
237  }
238 
240 
241  static void Copy(VectorType const& rX, VectorType& rY)
242  {
243 #ifndef _OPENMP
244  rY.assign(rX);
245 #else
246 
247  const int size = rX.size();
248  if (rY.size() != static_cast<unsigned int>(size))
249  rY.resize(size, false);
250 
251  #pragma omp parallel for
252  for (int i = 0; i < size; i++)
253  rY[i] = rX[i];
254 #endif
255  }
256 
258 
259  static TDataType Dot(VectorType const& rX, VectorType const& rY)
260  {
261 #ifndef _OPENMP
262  return inner_prod(rX, rY);
263 #else
264  const int size = static_cast<int>(rX.size());
265 
266  TDataType total = TDataType();
267  #pragma omp parallel for reduction( +: total), firstprivate(size)
268  for(int i =0; i<size; ++i)
269  total += rX[i]*rY[i];
270 
271  return total;
272 #endif
273  }
274 
275 
277 
278  static TDataType TwoNorm(VectorType const& rX)
279  {
280  return std::sqrt(Dot(rX, rX));
281  }
282 
283  static TDataType TwoNorm(const Matrix& rA) // Frobenious norm
284  {
285  TDataType aux_sum = TDataType();
286  #pragma omp parallel for reduction(+:aux_sum)
287  for (int i=0; i<static_cast<int>(rA.size1()); ++i) {
288  for (int j=0; j<static_cast<int>(rA.size2()); ++j) {
289  aux_sum += std::pow(rA(i,j),2);
290  }
291  }
292  return std::sqrt(aux_sum);
293  }
294 
295  static TDataType TwoNorm(const compressed_matrix<TDataType> & rA) // Frobenious norm
296  {
297  TDataType aux_sum = TDataType();
298 
299  const auto& r_values = rA.value_data();
300 
301  #pragma omp parallel for reduction(+:aux_sum)
302  for (int i=0; i<static_cast<int>(r_values.size()); ++i) {
303  aux_sum += std::pow(r_values[i] , 2);
304  }
305  return std::sqrt(aux_sum);
306  }
307 
313  static TDataType JacobiNorm(const Matrix& rA)
314  {
315  TDataType aux_sum = TDataType();
316  #pragma omp parallel for reduction(+:aux_sum)
317  for (int i=0; i<static_cast<int>(rA.size1()); ++i) {
318  for (int j=0; j<static_cast<int>(rA.size2()); ++j) {
319  if (i != j) {
320  aux_sum += std::abs(rA(i,j));
321  }
322  }
323  }
324  return aux_sum;
325  }
326 
327  static TDataType JacobiNorm(const compressed_matrix<TDataType>& rA)
328  {
329  TDataType aux_sum = TDataType();
330 
331  typedef typename compressed_matrix<TDataType>::const_iterator1 t_it_1;
332  typedef typename compressed_matrix<TDataType>::const_iterator2 t_it_2;
333 
334  for (t_it_1 it_1 = rA.begin1(); it_1 != rA.end1(); ++it_1) {
335  for (t_it_2 it_2 = it_1.begin(); it_2 != it_1.end(); ++it_2) {
336  if (it_2.index1() != it_2.index2()) {
337  aux_sum += std::abs(*it_2);
338  }
339  }
340  }
341  return aux_sum;
342  }
343 
344  static void Mult(const Matrix& rA, VectorType& rX, VectorType& rY)
345  {
346  axpy_prod(rA, rX, rY, true);
347  }
348 
349  static void Mult(const compressed_matrix<TDataType>& rA, VectorType& rX, VectorType& rY)
350  {
351 #ifndef _OPENMP
352  axpy_prod(rA, rX, rY, true);
353 #else
354  ParallelProductNoAdd(rA, rX, rY);
355 #endif
356  }
357 
358  template< class TOtherMatrixType >
359  static void TransposeMult(TOtherMatrixType& rA, VectorType& rX, VectorType& rY)
360  {
361  boost::numeric::ublas::axpy_prod(rX, rA, rY, true);
362  } // rY = rAT * rX
363 
364  static inline SizeType GraphDegree(IndexType i, TMatrixType& A)
365  {
366  typename MatrixType::iterator1 a_iterator = A.begin1();
367  std::advance(a_iterator, i);
368 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
369  return ( std::distance(a_iterator.begin(), a_iterator.end()));
370 #else
371  return ( std::distance(begin(a_iterator, boost::numeric::ublas::iterator1_tag()),
372  end(a_iterator, boost::numeric::ublas::iterator1_tag())));
373 #endif
374  }
375 
376  static inline void GraphNeighbors(IndexType i, TMatrixType& A, std::vector<IndexType>& neighbors)
377  {
378  neighbors.clear();
379  typename MatrixType::iterator1 a_iterator = A.begin1();
380  std::advance(a_iterator, i);
381 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
382  for (typename MatrixType::iterator2 row_iterator = a_iterator.begin();
383  row_iterator != a_iterator.end(); ++row_iterator)
384  {
385 #else
386  for (typename MatrixType::iterator2 row_iterator = begin(a_iterator,
387  boost::numeric::ublas::iterator1_tag());
388  row_iterator != end(a_iterator,
389  boost::numeric::ublas::iterator1_tag()); ++row_iterator)
390  {
391 #endif
392  neighbors.push_back(row_iterator.index2());
393  }
394  }
395 
396 
397  //********************************************************************
398  //checks if a multiplication is needed and tries to do otherwise
399 
400  static void InplaceMult(VectorType& rX, const double A)
401  {
402 
403  if (A == 1.00)
404  {
405  }
406  else if (A == -1.00)
407  {
408 #ifndef _OPENMP
409  typename VectorType::iterator x_iterator = rX.begin();
410  typename VectorType::iterator end_iterator = rX.end();
411  while (x_iterator != end_iterator)
412  {
413  *x_iterator = -*x_iterator;
414  x_iterator++;
415 
416  }
417 #else
418  const int size = rX.size();
419 
420  #pragma omp parallel for firstprivate(size)
421  for (int i = 0; i < size; i++)
422  rX[i] = -rX[i];
423 
424 #endif
425  }
426  else
427  {
428 #ifndef _OPENMP
429  rX *= A;
430 #else
431  const int size = rX.size();
432 
433  #pragma omp parallel for firstprivate(size)
434  for (int i = 0; i < size; i++)
435  rX[i] *= A;
436 #endif
437  }
438  }
439 
440  //********************************************************************
441  //checks if a multiplication is needed and tries to do otherwise
442  //ATTENTION it is assumed no aliasing between rX and rY
443  // X = A*y;
444 
445  static void Assign(VectorType& rX, const double A, const VectorType& rY)
446  {
447 #ifndef _OPENMP
448  if (A == 1.00)
449  noalias(rX) = rY;
450  else if (A == -1.00)
451  noalias(rX) = -rY;
452  else
453  noalias(rX) = A*rY;
454 #else
455  const int size = rY.size();
456  if (rX.size() != static_cast<unsigned int>(size) )
457  rX.resize(size, false);
458 
459  if (A == 1.00)
460  {
461  #pragma omp parallel for
462  for (int i = 0; i < size; i++)
463  rX[i] = rY[i];
464  }
465  else if (A == -1.00)
466  {
467  #pragma omp parallel for
468  for (int i = 0; i < size; i++)
469  rX[i] = -rY[i];
470  }
471  else
472  {
473  #pragma omp parallel for
474  for (int i = 0; i < size; i++)
475  rX[i] = A * rY[i];
476  }
477 #endif
478  }
479 
480  //********************************************************************
481  //checks if a multiplication is needed and tries to do otherwise
482  //ATTENTION it is assumed no aliasing between rX and rY
483  // X += A*y;
484 
485  static void UnaliasedAdd(VectorType& rX, const double A, const VectorType& rY)
486  {
487 #ifndef _OPENMP
488  if (A == 1.00)
489  noalias(rX) += rY;
490  else if (A == -1.00)
491  noalias(rX) -= rY;
492  else
493  noalias(rX) += A*rY;
494 #else
495  const int size = rY.size();
496  if (rX.size() != static_cast<unsigned int>(size) )
497  rX.resize(size, false);
498 
499  if (A == 1.00)
500  {
501  #pragma omp parallel for
502  for (int i = 0; i < size; i++)
503  rX[i] += rY[i];
504  }
505  else if (A == -1.00)
506  {
507  #pragma omp parallel for
508  for (int i = 0; i < size; i++)
509  rX[i] -= rY[i];
510  }
511  else
512  {
513  #pragma omp parallel for
514  for (int i = 0; i < size; i++)
515  rX[i] += A * rY[i];
516  }
517 
518 
519 #endif
520 
521  }
522 
523  //********************************************************************
524 
525  static void ScaleAndAdd(const double A, const VectorType& rX, const double B, const VectorType& rY, VectorType& rZ) // rZ = (A * rX) + (B * rY)
526  {
527  Assign(rZ, A, rX); //rZ = A*rX
528  UnaliasedAdd(rZ, B, rY); //rZ += B*rY
529  }
530 
531  static void ScaleAndAdd(const double A, const VectorType& rX, const double B, VectorType& rY) // rY = (A * rX) + (B * rY)
532  {
533  InplaceMult(rY, B);
534  UnaliasedAdd(rY, A, rX);
535  }
536 
537 
539 
540  static double RowDot(unsigned int i, MatrixType& rA, VectorType& rX)
541  {
542  return inner_prod(row(rA, i), rX);
543  }
544 
545 
546  static void SetValue(VectorType& rX, IndexType i, TDataType value)
547  {
548  rX[i] = value;
549  }
550 
552 
553  static void Set(VectorType& rX, TDataType A)
554  {
555  std::fill(rX.begin(), rX.end(), A);
556  }
557 
558  static void Resize(MatrixType& rA, SizeType m, SizeType n)
559  {
560  rA.resize(m, n, false);
561  }
562 
564  {
565  pA->resize(m, n, false);
566  }
567 
568  static void Resize(VectorType& rX, SizeType n)
569  {
570  rX.resize(n, false);
571  }
572 
573  static void Resize(VectorPointerType& pX, SizeType n)
574  {
575  pX->resize(n, false);
576  }
577 
578  static void Clear(MatrixPointerType& pA)
579  {
580  pA->clear();
581  pA->resize(0, 0, false);
582  }
583 
584  static void Clear(VectorPointerType& pX)
585  {
586  pX->clear();
587  pX->resize(0, false);
588  }
589 
590  template<class TOtherMatrixType>
591  inline static void ResizeData(TOtherMatrixType& rA, SizeType m)
592  {
593  rA.resize(m, false);
594  // std::fill(rA.begin(), rA.end(), TDataType());
595 #ifndef _OPENMP
596  std::fill(rA.begin(), rA.end(), TDataType());
597 #else
598  DataType* vals = rA.value_data().begin();
599  #pragma omp parallel for firstprivate(m)
600  for(int i=0; i<static_cast<int>(m); ++i)
601  vals[i] = TDataType();
602 #endif
603  }
604 
605  inline static void ResizeData(compressed_matrix<TDataType>& rA, SizeType m)
606  {
607  rA.value_data().resize(m);
608 #ifndef _OPENMP
609  std::fill(rA.value_data().begin(), rA.value_data().end(), TDataType());
610 #else
611  TDataType* vals = rA.value_data().begin();
612  #pragma omp parallel for firstprivate(m)
613  for(int i=0; i<static_cast<int>(m); ++i)
614  vals[i] = TDataType();
615 #endif
616  }
617 
618  inline static void ResizeData(VectorType& rX, SizeType m)
619  {
620  rX.resize(m, false);
621 #ifndef _OPENMP
622  std::fill(rX.begin(), rX.end(), TDataType());
623 #else
624  const int size = rX.size();
625  #pragma omp parallel for firstprivate(size)
626  for(int i=0; i<size; ++i)
627  rX[i] = TDataType();
628 #endif
629  }
630 
631  template<class TOtherMatrixType>
632  inline static void SetToZero(TOtherMatrixType& rA)
633  {
634 #ifndef _OPENMP
635  std::fill(rA.begin(), rA.end(), TDataType());
636 #else
637  TDataType* vals = rA.value_data().begin();
638  const int size = rA.value_data().end() - rA.value_data().begin();
639  #pragma omp parallel for firstprivate(size)
640  for(int i=0; i<size; ++i)
641  vals[i] = TDataType();
642 #endif
643  }
644 
645  inline static void SetToZero(compressed_matrix<TDataType>& rA)
646  {
647 #ifndef _OPENMP
648  std::fill(rA.value_data().begin(), rA.value_data().end(), TDataType());
649 #else
650  TDataType* vals = rA.value_data().begin();
651  const int size = rA.value_data().end() - rA.value_data().begin();
652  #pragma omp parallel for firstprivate(size)
653  for(int i=0; i<size; ++i)
654  vals[i] = TDataType();
655 #endif
656  }
657 
658  inline static void SetToZero(VectorType& rX)
659  {
660 #ifndef _OPENMP
661  std::fill(rX.begin(), rX.end(), TDataType());
662 #else
663  const int size = rX.size();
664  #pragma omp parallel for firstprivate(size)
665  for(int i=0; i<size; ++i)
666  rX[i] = TDataType();
667 #endif
668  }
669 
670  template<class TOtherMatrixType, class TEquationIdVectorType>
671  inline static void AssembleLHS(
672  MatrixType& A,
673  TOtherMatrixType& LHS_Contribution,
674  TEquationIdVectorType& EquationId
675  )
676  {
677  unsigned int system_size = A.size1();
678  unsigned int local_size = LHS_Contribution.size1();
679 
680  for (unsigned int i_local = 0; i_local < local_size; i_local++)
681  {
682  unsigned int i_global = EquationId[i_local];
683  if (i_global < system_size)
684  {
685  for (unsigned int j_local = 0; j_local < local_size; j_local++)
686  {
687  unsigned int j_global = EquationId[j_local];
688  if (j_global < system_size)
689  A(i_global, j_global) += LHS_Contribution(i_local, j_local);
690  }
691  }
692  }
693  }
694 
705  const ProcessInfo& rProcessInfo,
706  MatrixType& rA,
707  VectorType& rb,
708  const SCALING_DIAGONAL ScalingDiagonal = SCALING_DIAGONAL::NO_SCALING
709  )
710  {
711  const std::size_t system_size = rA.size1();
712 
713  const double* Avalues = rA.value_data().begin();
714  const std::size_t* Arow_indices = rA.index1_data().begin();
715 
716  // Define zero value tolerance
717  const double zero_tolerance = std::numeric_limits<double>::epsilon();
718 
719  // The diagonal considered
720  const double scale_factor = GetScaleNorm(rProcessInfo, rA, ScalingDiagonal);
721 
722  // Detect if there is a line of all zeros and set the diagonal to a 1 if this happens
723  IndexPartition(system_size).for_each([&](std::size_t Index){
724  bool empty = true;
725 
726  const std::size_t col_begin = Arow_indices[Index];
727  const std::size_t col_end = Arow_indices[Index + 1];
728 
729  for (std::size_t j = col_begin; j < col_end; ++j) {
730  if(std::abs(Avalues[j]) > zero_tolerance) {
731  empty = false;
732  break;
733  }
734  }
735 
736  if(empty) {
737  rA(Index, Index) = scale_factor;
738  rb[Index] = 0.0;
739  }
740  });
741 
742  return scale_factor;
743  }
744 
752  static double GetScaleNorm(
753  const ProcessInfo& rProcessInfo,
754  const MatrixType& rA,
755  const SCALING_DIAGONAL ScalingDiagonal = SCALING_DIAGONAL::NO_SCALING
756  )
757  {
758  switch (ScalingDiagonal) {
760  return 1.0;
762  KRATOS_ERROR_IF_NOT(rProcessInfo.Has(BUILD_SCALE_FACTOR)) << "Scale factor not defined at process info" << std::endl;
763  return rProcessInfo.GetValue(BUILD_SCALE_FACTOR);
764  }
766  return GetDiagonalNorm(rA)/static_cast<double>(rA.size1());
768  return GetMaxDiagonal(rA);
769  default:
770  return GetMaxDiagonal(rA);
771  }
772  }
773 
779  static double GetDiagonalNorm(const MatrixType& rA)
780  {
781  const double* Avalues = rA.value_data().begin();
782  const std::size_t* Arow_indices = rA.index1_data().begin();
783  const std::size_t* Acol_indices = rA.index2_data().begin();
784 
785  const double diagonal_norm = IndexPartition<std::size_t>(Size1(rA)).for_each<SumReduction<double>>([&](std::size_t Index){
786  const std::size_t col_begin = Arow_indices[Index];
787  const std::size_t col_end = Arow_indices[Index+1];
788  for (std::size_t j = col_begin; j < col_end; ++j) {
789  if (Acol_indices[j] == Index ) {
790  return std::pow(Avalues[j], 2);
791  }
792  }
793  return 0.0;
794  });
795 
796  return std::sqrt(diagonal_norm);
797  }
798 
804  static double GetAveragevalueDiagonal(const MatrixType& rA)
805  {
806  return 0.5 * (GetMaxDiagonal(rA) + GetMinDiagonal(rA));
807  }
808 
814  static double GetMaxDiagonal(const MatrixType& rA)
815  {
816  const double* Avalues = rA.value_data().begin();
817  const std::size_t* Arow_indices = rA.index1_data().begin();
818  const std::size_t* Acol_indices = rA.index2_data().begin();
819 
821  const std::size_t col_begin = Arow_indices[Index];
822  const std::size_t col_end = Arow_indices[Index+1];
823  for (std::size_t j = col_begin; j < col_end; ++j) {
824  if (Acol_indices[j] == Index ) {
825  return std::abs(Avalues[j]);
826  }
827  }
828  return std::numeric_limits<double>::lowest();
829  });
830  }
831 
837  static double GetMinDiagonal(const MatrixType& rA)
838  {
839  const double* Avalues = rA.value_data().begin();
840  const std::size_t* Arow_indices = rA.index1_data().begin();
841  const std::size_t* Acol_indices = rA.index2_data().begin();
842 
844  const std::size_t col_begin = Arow_indices[Index];
845  const std::size_t col_end = Arow_indices[Index+1];
846  for (std::size_t j = col_begin; j < col_end; ++j) {
847  if (Acol_indices[j] == Index ) {
848  return std::abs(Avalues[j]);
849  }
850  }
852  });
853  }
854 
858 
862 
866 
868 
869  virtual std::string Info() const
870  {
871  return "UBlasSpace";
872  }
873 
875 
876  virtual void PrintInfo(std::ostream& rOStream) const
877  {
878  rOStream << "UBlasSpace";
879  }
880 
882 
883  virtual void PrintData(std::ostream& rOStream) const
884  {
885  }
886 
887  //***********************************************************************
888 
889  inline static constexpr bool IsDistributed()
890  {
891  return false;
892  }
893 
894  //***********************************************************************
895 
896  inline static TDataType GetValue(const VectorType& x, std::size_t I)
897  {
898  return x[I];
899  }
900  //***********************************************************************
901 
902  static void GatherValues(const VectorType& x, const std::vector<std::size_t>& IndexArray, TDataType* pValues)
903  {
904  KRATOS_TRY
905 
906  for (std::size_t i = 0; i < IndexArray.size(); i++)
907  pValues[i] = x[IndexArray[i]];
908 
909  KRATOS_CATCH("")
910  }
911 
912  template< class TOtherMatrixType >
913  static bool WriteMatrixMarketMatrix(const char* pFileName, /*const*/ TOtherMatrixType& rM, const bool Symmetric)
914  {
915  // Use full namespace in call to make sure we are not calling this function recursively
916  return Kratos::WriteMatrixMarketMatrix(pFileName, rM, Symmetric);
917  }
918 
919  template< class VectorType >
920  static bool WriteMatrixMarketVector(const char* pFileName, const VectorType& rV)
921  {
922  // Use full namespace in call to make sure we are not calling this function recursively
923  return Kratos::WriteMatrixMarketVector(pFileName, rV);
924  }
925 
927  {
929  return tmp.Create();
930  }
931 
937  static constexpr bool IsDistributedSpace()
938  {
939  return false;
940  }
941 
945 
947 protected:
950 
954 
958 
962 
966 
970 
974 
976 private:
979 
983 
987 
988 #ifdef _OPENMP
989  //y += A*x in parallel
990 
991  static void ParallelProductNoAdd(const MatrixType& A, const VectorType& in, VectorType& out)
992  {
993  //create partition
994  DenseVector<unsigned int> partition;
995  unsigned int number_of_threads = omp_get_max_threads();
996  unsigned int number_of_initialized_rows = A.filled1() - 1;
997  CreatePartition(number_of_threads, number_of_initialized_rows, partition);
998  //parallel loop
999  #pragma omp parallel
1000  {
1001  int thread_id = omp_get_thread_num();
1002  int number_of_rows = partition[thread_id + 1] - partition[thread_id];
1003  typename compressed_matrix<TDataType>::index_array_type::const_iterator row_iter_begin = A.index1_data().begin() + partition[thread_id];
1004  typename compressed_matrix<TDataType>::index_array_type::const_iterator index_2_begin = A.index2_data().begin()+*row_iter_begin;
1005  typename compressed_matrix<TDataType>::value_array_type::const_iterator value_begin = A.value_data().begin()+*row_iter_begin;
1006  // typename VectorType::iterator output_vec_begin = out.begin()+partition[thread_id];
1007 
1008 
1009  partial_product_no_add(number_of_rows,
1010  row_iter_begin,
1011  index_2_begin,
1012  value_begin,
1013  in,
1014  partition[thread_id],
1015  out
1016  );
1017  }
1018  }
1019 
1020  static void CreatePartition(unsigned int number_of_threads, const int number_of_rows, DenseVector<unsigned int>& partitions)
1021  {
1022  partitions.resize(number_of_threads + 1);
1023  int partition_size = number_of_rows / number_of_threads;
1024  partitions[0] = 0;
1025  partitions[number_of_threads] = number_of_rows;
1026  for (unsigned int i = 1; i < number_of_threads; i++)
1027  partitions[i] = partitions[i - 1] + partition_size;
1028  }
1029 
1030 
1034  static void partial_product_no_add(
1035  int number_of_rows,
1036  typename compressed_matrix<TDataType>::index_array_type::const_iterator row_begin,
1037  typename compressed_matrix<TDataType>::index_array_type::const_iterator index2_begin,
1038  typename compressed_matrix<TDataType>::value_array_type::const_iterator value_begin,
1039  const VectorType& input_vec,
1040  unsigned int output_begin_index,
1041  VectorType& output_vec
1042  // typename VectorType::iterator output_vec_begin
1043  )
1044  {
1045  int row_size;
1046  int kkk = output_begin_index;
1047  typename MatrixType::index_array_type::const_iterator row_it = row_begin;
1048  for (int k = 0; k < number_of_rows; k++)
1049  {
1050  row_size = *(row_it + 1)-*row_it;
1051  row_it++;
1052  TDataType t = TDataType();
1053 
1054  for (int i = 0; i < row_size; i++)
1055  t += *value_begin++ * (input_vec[*index2_begin++]);
1056 
1057  output_vec[kkk++] = t;
1058  // *output_vec_begin++ = t;
1059 
1060  }
1061  }
1062 #endif
1063 
1067 
1071 
1075 
1079 
1081  UblasSpace & operator=(UblasSpace const& rOther);
1082 
1084  UblasSpace(UblasSpace const& rOther);
1085 
1087 }; // Class UblasSpace
1088 
1092 
1096 
1098 // inline std::istream& operator >> (std::istream& rIStream,
1099 // UblasSpace& rThis);
1100 
1101 // /// output stream function
1102 // inline std::ostream& operator << (std::ostream& rOStream,
1103 // const UblasSpace& rThis)
1104 // {
1105 // rThis.PrintInfo(rOStream);
1106 // rOStream << std::endl;
1107 // rThis.PrintData(rOStream);
1108 
1109 // return rOStream;
1110 // }
1112 
1113 
1114 } // namespace Kratos.
bool Has(const Variable< TDataType > &rThisVariable) const
Checks if the data container has a value associated with a given variable.
Definition: data_value_container.h:382
TDataType & GetValue(const Variable< TDataType > &rThisVariable)
Gets the value associated with a given variable.
Definition: data_value_container.h:268
Utility class to update the values of degree of freedom (Dof) variables after solving the system.
Definition: dof_updater.h:40
This class is useful for index iteration over containers.
Definition: parallel_utilities.h:451
void for_each(TUnaryFunction &&f)
Definition: parallel_utilities.h:514
Definition: amatrix_interface.h:41
Definition: reduction_utilities.h:128
Definition: reduction_utilities.h:190
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
utility function to do a sum reduction
Definition: reduction_utilities.h:68
A class template for handling data types, matrices, and vectors in a Ublas space.
Definition: ublas_space.h:121
TDataType DataType
The data type considered.
Definition: ublas_space.h:130
static void Set(VectorType &rX, TDataType A)
rX = A
Definition: ublas_space.h:553
typename Kratos::shared_ptr< TVectorType > VectorPointerType
The pointer to the vector type.
Definition: ublas_space.h:148
static void Resize(VectorType &rX, SizeType n)
Definition: ublas_space.h:568
static void Resize(MatrixType &rA, SizeType m, SizeType n)
Definition: ublas_space.h:558
static void Resize(VectorPointerType &pX, SizeType n)
Definition: ublas_space.h:573
std::size_t SizeType
The size type considered.
Definition: ublas_space.h:142
static constexpr bool IsDistributed()
Definition: ublas_space.h:889
static void UnaliasedAdd(VectorType &rX, const double A, const VectorType &rY)
Definition: ublas_space.h:485
static void Copy(VectorType const &rX, VectorType &rY)
rY = rX
Definition: ublas_space.h:241
static void GetColumn(unsigned int j, Matrix &rM, TColumnType &rX)
rXi = rMij
Definition: ublas_space.h:212
static void SetToZero(TOtherMatrixType &rA)
Definition: ublas_space.h:632
static void AssembleLHS(MatrixType &A, TOtherMatrixType &LHS_Contribution, TEquationIdVectorType &EquationId)
Definition: ublas_space.h:671
static void ScaleAndAdd(const double A, const VectorType &rX, const double B, const VectorType &rY, VectorType &rZ)
Definition: ublas_space.h:525
static TDataType TwoNorm(VectorType const &rX)
||rX||2
Definition: ublas_space.h:278
static void ResizeData(compressed_matrix< TDataType > &rA, SizeType m)
Definition: ublas_space.h:605
static TDataType Dot(VectorType const &rX, VectorType const &rY)
rX * rY
Definition: ublas_space.h:259
typename DofUpdaterType::UniquePointer DofUpdaterPointerType
The pointer to the DoF updater type.
Definition: ublas_space.h:154
static void GatherValues(const VectorType &x, const std::vector< std::size_t > &IndexArray, TDataType *pValues)
Definition: ublas_space.h:902
static IndexType Size1(MatrixType const &rM)
return number of rows of rM
Definition: ublas_space.h:197
static void TransposeMult(TOtherMatrixType &rA, VectorType &rX, VectorType &rY)
Definition: ublas_space.h:359
static void SetColumn(unsigned int j, Matrix &rM, TColumnType &rX)
Definition: ublas_space.h:224
static TDataType GetValue(const VectorType &x, std::size_t I)
Definition: ublas_space.h:896
UblasSpace()
Default constructor.
Definition: ublas_space.h:161
static void Mult(const compressed_matrix< TDataType > &rA, VectorType &rX, VectorType &rY)
Definition: ublas_space.h:349
static void ResizeData(VectorType &rX, SizeType m)
Definition: ublas_space.h:618
static double RowDot(unsigned int i, MatrixType &rA, VectorType &rX)
rA[i] * rX
Definition: ublas_space.h:540
static double GetScaleNorm(const ProcessInfo &rProcessInfo, const MatrixType &rA, const SCALING_DIAGONAL ScalingDiagonal=SCALING_DIAGONAL::NO_SCALING)
This method returns the scale norm considering for scaling the diagonal.
Definition: ublas_space.h:752
static bool WriteMatrixMarketVector(const char *pFileName, const VectorType &rV)
Definition: ublas_space.h:920
static bool WriteMatrixMarketMatrix(const char *pFileName, TOtherMatrixType &rM, const bool Symmetric)
Definition: ublas_space.h:913
typename Kratos::shared_ptr< TMatrixType > MatrixPointerType
The pointer to the matrix type.
Definition: ublas_space.h:145
static TDataType TwoNorm(const compressed_matrix< TDataType > &rA)
Definition: ublas_space.h:295
static void ScaleAndAdd(const double A, const VectorType &rX, const double B, VectorType &rY)
Definition: ublas_space.h:531
static void SetToZero(compressed_matrix< TDataType > &rA)
Definition: ublas_space.h:645
static double GetAveragevalueDiagonal(const MatrixType &rA)
This method returns the diagonal max value.
Definition: ublas_space.h:804
static void GraphNeighbors(IndexType i, TMatrixType &A, std::vector< IndexType > &neighbors)
Definition: ublas_space.h:376
static MatrixPointerType CreateEmptyMatrixPointer()
Definition: ublas_space.h:178
virtual ~UblasSpace()
Destructor.
Definition: ublas_space.h:166
static TDataType JacobiNorm(const compressed_matrix< TDataType > &rA)
Definition: ublas_space.h:327
static void SetValue(VectorType &rX, IndexType i, TDataType value)
Definition: ublas_space.h:546
static DofUpdaterPointerType CreateDofUpdater()
Definition: ublas_space.h:926
static void SetToZero(VectorType &rX)
Definition: ublas_space.h:658
KRATOS_CLASS_POINTER_DEFINITION(UblasSpace)
Pointer definition of UblasSpace.
static void Copy(MatrixType const &rX, MatrixType &rY)
rY = rX
Definition: ublas_space.h:234
static void Clear(VectorPointerType &pX)
Definition: ublas_space.h:584
static void Clear(MatrixPointerType &pA)
Definition: ublas_space.h:578
static VectorPointerType CreateEmptyVectorPointer()
Definition: ublas_space.h:183
static void InplaceMult(VectorType &rX, const double A)
Definition: ublas_space.h:400
TMatrixType MatrixType
The matrix type considered.
Definition: ublas_space.h:133
static void Assign(VectorType &rX, const double A, const VectorType &rY)
Definition: ublas_space.h:445
static IndexType Size(VectorType const &rV)
return size of vector rV
Definition: ublas_space.h:190
virtual void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: ublas_space.h:876
static TDataType TwoNorm(const Matrix &rA)
Definition: ublas_space.h:283
static double GetMinDiagonal(const MatrixType &rA)
This method returns the diagonal min value.
Definition: ublas_space.h:837
static double GetDiagonalNorm(const MatrixType &rA)
This method returns the diagonal norm considering for scaling the diagonal.
Definition: ublas_space.h:779
static IndexType Size2(MatrixType const &rM)
return number of columns of rM
Definition: ublas_space.h:204
std::size_t IndexType
The index type considered.
Definition: ublas_space.h:139
static double GetMaxDiagonal(const MatrixType &rA)
This method returns the diagonal max value.
Definition: ublas_space.h:814
static SizeType GraphDegree(IndexType i, TMatrixType &A)
Definition: ublas_space.h:364
static constexpr bool IsDistributedSpace()
Check if the UblasSpace is distributed.
Definition: ublas_space.h:937
virtual std::string Info() const
Turn back information as a string.
Definition: ublas_space.h:869
virtual void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: ublas_space.h:883
static TDataType JacobiNorm(const Matrix &rA)
Definition: ublas_space.h:313
static void Mult(const Matrix &rA, VectorType &rX, VectorType &rY)
Definition: ublas_space.h:344
static void Resize(MatrixPointerType &pA, SizeType m, SizeType n)
Definition: ublas_space.h:563
TVectorType VectorType
The vector type considered.
Definition: ublas_space.h:136
static void ResizeData(TOtherMatrixType &rA, SizeType m)
Definition: ublas_space.h:591
static double CheckAndCorrectZeroDiagonalValues(const ProcessInfo &rProcessInfo, MatrixType &rA, VectorType &rb, const SCALING_DIAGONAL ScalingDiagonal=SCALING_DIAGONAL::NO_SCALING)
This method checks and corrects the zero diagonal values.
Definition: ublas_space.h:704
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_ERROR_IF_NOT(conditional)
Definition: exception.h:163
end
Definition: DEM_benchmarks.py:180
static double max(double a, double b)
Definition: GeometryFunctions.h:79
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
std::shared_ptr< T > shared_ptr
Definition: smart_pointers.h:27
bool WriteMatrixMarketVector(const char *FileName, VectorType &V)
Definition: matrix_market_interface.h:539
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
bool WriteMatrixMarketMatrix(const char *FileName, CompressedMatrixType &M, bool Symmetric)
Definition: matrix_market_interface.h:308
SCALING_DIAGONAL
Definition: ublas_space.h:98
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
AMatrix::MatrixRow< const TExpressionType > row(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression, std::size_t RowIndex)
Definition: amatrix_interface.h:649
int local_size
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:17
tuple tmp
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:98
def Index()
Definition: hdf5_io_tools.py:38
out
Definition: isotropic_damage_automatic_differentiation.py:200
int t
Definition: ode_solve.py:392
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
int m
Definition: run_marine_rain_substepping.py:8
A
Definition: sensitivityMatrix.py:70
x
Definition: sensitivityMatrix.py:49
B
Definition: sensitivityMatrix.py:76
integer i
Definition: TensorModule.f:17