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.
mpi_communicator.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: Pooyan Dadvand
11 // Riccardo Rossi
12 //
13 //
14 
15 #if !defined(KRATOS_MPI_COMMUNICATOR_H_INCLUDED )
16 #define KRATOS_MPI_COMMUNICATOR_H_INCLUDED
17 
18 // System includes
19 #include <string>
20 #include <iostream>
21 #include <sstream>
22 #include <cstddef>
23 
24 // External includes
25 #include "mpi.h"
26 
27 // Project includes
29 #include "includes/define.h"
30 #include "includes/model_part.h"
33 
34 #define CUSTOMTIMER 1
35 
36 /* Timer defines */
37 #include "utilities/timer.h"
38 #ifdef CUSTOMTIMER
39 #define KRATOS_TIMER_START(t) Timer::Start(t);
40 #define KRATOS_TIMER_STOP(t) Timer::Stop(t);
41 #else
42 #define KRATOS_TIMER_START(t)
43 #define KRATOS_TIMER_STOP(t)
44 #endif
45 
46 
47 namespace Kratos
48 {
49 
52 
56 
60 
64 
68 
69 namespace MPIInternals
70 {
71 
72 template<class ValueType> struct SendTraits;
73 
74 template<> struct SendTraits<int>
75 {
76  using SendType = int;
77  using BufferType = std::vector<SendType>;
78  constexpr static bool IsFixedSize = true;
79  constexpr static std::size_t BlockSize = 1;
80 };
81 
82 template<> struct SendTraits<bool>
83 {
84  using SendType = int; // Note: sending bool as int to avoid the problems of std::vector<bool>
85  using BufferType = std::vector<SendType>;
86  constexpr static bool IsFixedSize = true;
87  constexpr static std::size_t BlockSize = 1;
88 };
89 
90 template<> struct SendTraits<double>
91 {
92  using SendType = double;
93  using BufferType = std::vector<SendType>;
94  constexpr static bool IsFixedSize = true;
95  constexpr static std::size_t BlockSize = 1;
96 };
97 
98 template<std::size_t TDim> struct SendTraits< array_1d<double,TDim> >
99 {
100  using SendType = double;
101  using BufferType = std::vector<SendType>;
102  constexpr static bool IsFixedSize = true;
103  constexpr static std::size_t BlockSize = TDim;
104 };
105 
106 template<> struct SendTraits< Kratos::Flags >
107 {
108  using SendType = double;
109  using BufferType = std::vector<SendType>;
110  constexpr static bool IsFixedSize = true;
111  constexpr static std::size_t BlockSize = sizeof(Kratos::Flags)/sizeof(double);
112 };
113 
114 template<> struct SendTraits< Vector >
115 {
116  using SendType = double;
117  using BufferType = std::vector<SendType>;
118  constexpr static bool IsFixedSize = false;
119 
120  static inline std::size_t GetMessageSize(const Vector& rValue)
121  {
122  return rValue.size();
123  }
124 };
125 
126 template<> struct SendTraits< Matrix >
127 {
128  using SendType = double;
129  using BufferType = std::vector<SendType>;
130  constexpr static bool IsFixedSize = false;
131 
132  static inline std::size_t GetMessageSize(const Matrix& rValue)
133  {
134  return rValue.data().size();
135  }
136 };
137 
138 template<> struct SendTraits< Quaternion<double> >
139 {
140  using SendType = double;
141  using BufferType = std::vector<SendType>;
142  constexpr static bool IsFixedSize = true;
143  constexpr static std::size_t BlockSize = 4;
144 };
145 
146 template<typename TVectorValue> struct SendTraits< DenseVector<TVectorValue> >
147 {
148  using SendType = double;
149  using BufferType = std::vector<SendType>;
150  constexpr static bool IsFixedSize = false;
151 
152  static inline std::size_t GetMessageSize(const DenseVector<TVectorValue>& rValue)
153  {
154  return rValue.size()*sizeof(TVectorValue)/sizeof(double);
155  }
156 };
157 
158 
160 {
161  using SendType = double;
162  using BufferType = std::string;
163  constexpr static bool IsFixedSize = false;
164 
165  static inline std::size_t GetMessageSize(const Kratos::VariablesListDataValueContainer& rValue)
166  {
167  return (rValue.TotalSize()+1)*sizeof(char);
168  }
169 };
170 
171 template<> struct SendTraits< Node::DofsContainerType >
172 {
173  using SendType = int;
174  using BufferType = std::vector<SendType>;
175  constexpr static bool IsFixedSize = false;
176 
177  static inline std::size_t GetMessageSize(const Node::DofsContainerType& rValue)
178  {
179  return rValue.size();
180  }
181 };
182 
183 template<typename ValueType> struct DirectCopyTransfer
184 {
186 
187  static inline void WriteBuffer(const ValueType& rValue, SendType* pBuffer)
188  {
189  *(ValueType*)(pBuffer) = rValue;
190  }
191 
192  static inline void ReadBuffer(const SendType* pBuffer, ValueType& rValue)
193  {
194  rValue = *(reinterpret_cast<const ValueType*>(pBuffer));
195  }
196 };
197 
198 template<typename ValueType> struct DynamicArrayTypeTransfer
199 {
201 
202  static inline void WriteBuffer(const ValueType& rValue, SendType* pBuffer)
203  {
204  std::memcpy(pBuffer, &(rValue.data()[0]), rValue.data().size()*sizeof(double));
205  }
206 
207  static inline void ReadBuffer(const SendType* pBuffer, ValueType& rValue)
208  {
209  std::memcpy(&(rValue.data()[0]), pBuffer, rValue.data().size()*sizeof(double));
210  }
211 };
212 
213 template<class TValue> struct SendTools;
214 
215 template<>
216 struct SendTools<int> : public DirectCopyTransfer<int> {};
217 
218 template<>
219 struct SendTools<double>: public DirectCopyTransfer<double> {};
220 
221 template<>
222 struct SendTools<bool>: public DirectCopyTransfer<bool> {};
223 
224 template<std::size_t TDim>
225 struct SendTools< array_1d<double,TDim> >: public DirectCopyTransfer<array_1d<double,TDim>> {};
226 
227 template<>
228 struct SendTools< Kratos::Flags >: public DirectCopyTransfer<Kratos::Flags> {};
229 
230 template<>
231 struct SendTools< Vector >: public DynamicArrayTypeTransfer<Vector> {};
232 
233 template<>
234 struct SendTools< Matrix >: public DynamicArrayTypeTransfer<Matrix> {};
235 
236 // template<>
237 // struct SendTools< Quaternion<double> >: public DirectCopyTransfer<Quaternion<double>> {};
238 
239 template<>
241 {
243 
244  static inline void WriteBuffer(const Quaternion<double>& rValue, SendType* pBuffer)
245  {
246  *(pBuffer) = rValue.X();
247  *(pBuffer + 1) = rValue.Y();
248  *(pBuffer + 2) = rValue.Z();
249  *(pBuffer + 3) = rValue.W();
250  }
251 
252  static inline void ReadBuffer(const SendType* pBuffer, Quaternion<double>& rValue)
253  {
254  rValue.SetX(*(pBuffer));
255  rValue.SetY(*(pBuffer + 1));
256  rValue.SetZ(*(pBuffer + 2));
257  rValue.SetW(*(pBuffer + 3));
258  }
259 };
260 
261 template<typename TVectorValue>
262 struct SendTools< DenseVector<TVectorValue> >
263 {
265 
266  static inline void WriteBuffer(const DenseVector<TVectorValue>& rValue, SendType* pBuffer)
267  {
268  std::memcpy(pBuffer, &(rValue.data()[0]), rValue.size()*sizeof(TVectorValue));
269  }
270 
271  static inline void ReadBuffer(const SendType* pBuffer, DenseVector<TVectorValue>& rValue)
272  {
273  std::size_t position = 0;
274  for (unsigned int i = 0; i < rValue.size(); i++)
275  {
276  rValue[i] = *(reinterpret_cast<const TVectorValue*>(pBuffer + position));
277  position += sizeof(TVectorValue) / sizeof(double);
278  }
279  }
280 };
281 
283 {
285 
286  static inline void WriteBuffer(const Kratos::VariablesListDataValueContainer& rValue, SendType* pBuffer)
287  {
288  std::memcpy(pBuffer, rValue.Data(), rValue.TotalSize() * sizeof(double));
289  }
290 
291  static inline void ReadBuffer(const SendType* pBuffer, Kratos::VariablesListDataValueContainer& rValue)
292  {
293  std::memcpy(rValue.Data(), pBuffer, rValue.TotalSize() * sizeof(double));
294  }
295 };
296 
297 template<> struct SendTools< Node::DofsContainerType >
298 {
300 
301  static inline void WriteBuffer(const Node::DofsContainerType& rValue, SendType* pBuffer)
302  {
303  unsigned int i = 0;
304  for (auto i_dof = rValue.begin(); i_dof != rValue.end(); ++i_dof)
305  {
306  *(pBuffer + i) = (*i_dof)->EquationId();
307  ++i;
308  }
309  }
310 
311  static inline void ReadBuffer(const SendType* pBuffer, Node::DofsContainerType& rValue)
312  {
313  unsigned int i = 0;
314  for (auto i_dof = rValue.begin(); i_dof != rValue.end(); ++i_dof)
315  {
316  (*i_dof)->SetEquationId(*(pBuffer + i));
317  ++i;
318  }
319  }
320 };
321 
322 template<
323  class TDatabaseAccess,
324  bool IsFixedSize = SendTraits<typename TDatabaseAccess::ValueType>::IsFixedSize >
326  using ValueType = typename TDatabaseAccess::ValueType;
327  static inline std::size_t GetSendSize(TDatabaseAccess& rAccess, const Communicator::MeshType& rSourceMesh);
328  static inline std::size_t GetSendSize(const ValueType& rValue);
329 };
330 
331 template<class TDatabaseAccess>
332 struct BufferAllocation<TDatabaseAccess, true> {
333  using ValueType = typename TDatabaseAccess::ValueType;
334  static inline std::size_t GetSendSize(TDatabaseAccess& rAccess, const Communicator::MeshType& rSourceMesh)
335  {
336  const auto& r_container = rAccess.GetContainer(rSourceMesh);
337  std::size_t num_objects = r_container.size();
338  return num_objects * SendTraits<ValueType>::BlockSize;
339  }
340 
341  static inline std::size_t GetSendSize(const ValueType&)
342  {
344  }
345 };
346 
347 template<class TDatabaseAccess>
348 struct BufferAllocation<TDatabaseAccess, false> {
349  using ValueType = typename TDatabaseAccess::ValueType;
350  static inline std::size_t GetSendSize(TDatabaseAccess& rAccess, const Communicator::MeshType& rSourceMesh)
351  {
352  const auto& r_container = rAccess.GetContainer(rSourceMesh);
353  std::size_t buffer_size = 0;
354  for (auto iter = r_container.begin(); iter != r_container.end(); ++iter)
355  {
356  buffer_size += MPIInternals::SendTraits<ValueType>::GetMessageSize(rAccess.GetValue(iter));
357  }
358 
359  return buffer_size;
360  }
361 
362  static inline std::size_t GetSendSize(const ValueType& rValue)
363  {
365  }
366 };
367 
369 public:
370 
374 
376  {
377  return rMesh.Nodes();
378  }
379 
381  {
382  return rMesh.Nodes();
383  }
384 };
385 
387 public:
388 
392 
394  {
395  return rMesh.Elements();
396  }
397 
399  {
400  return rMesh.Elements();
401  }
402 };
403 
404 template<class TValue> class NodalSolutionStepValueAccess: public NodalContainerAccess
405 {
406  const Variable<TValue>& mrVariable;
407 
408 public:
409 
410  using ValueType = TValue;
412 
415  mrVariable(mrVariable)
416  {}
417 
418  TValue& GetValue(IteratorType& iter)
419  {
420  return iter->FastGetSolutionStepValue(mrVariable);
421  }
422 
423  const TValue& GetValue(const ConstIteratorType& iter)
424  {
425  return iter->FastGetSolutionStepValue(mrVariable);
426  }
427 };
428 
429 template<class TValue> class NodalDataAccess: public NodalContainerAccess
430 {
431  const Variable<TValue>& mrVariable;
432 
433 public:
434 
435  using ValueType = TValue;
437 
438  NodalDataAccess(const Variable<TValue>& mrVariable):
440  mrVariable(mrVariable)
441  {}
442 
443  TValue& GetValue(IteratorType& iter)
444  {
445  return iter->GetValue(mrVariable);
446  }
447 
448  const TValue& GetValue(const ConstIteratorType& iter)
449  {
450  return iter->GetValue(mrVariable);
451  }
452 };
453 
455 {
456 public:
457 
459 
462 
465  mrMask(rMask)
466  {}
467 
469  {
470  return *iter;
471  }
472 
474  {
475  return *iter;
476  }
477 };
478 
480 {
481 public:
482 
485 
487  {
488  return iter->SolutionStepData();
489  }
490 
492  {
493  return iter->SolutionStepData();
494  }
495 };
496 
498 {
499 public:
500 
503 
505  {
506  return iter->GetDofs();
507  }
508 
510  {
511  return iter->GetDofs();
512  }
513 };
514 
515 template<class TValue> class ElementalDataAccess: public ElementalContainerAccess
516 {
517  const Variable<TValue>& mrVariable;
518 
519 public:
520 
521  using ValueType = TValue;
523 
526  mrVariable(mrVariable)
527  {}
528 
529  TValue& GetValue(IteratorType& iter)
530  {
531  return iter->GetValue(mrVariable);
532  }
533 
534  const TValue& GetValue(const ConstIteratorType& iter)
535  {
536  return iter->GetValue(mrVariable);
537  }
538 };
539 
541 {
542 public:
543 
545 
548 
551  mrMask(rMask)
552  {}
553 
555  {
556  return *iter;
557  }
558 
560  {
561  return *iter;
562  }
563 };
564 
565 }
566 
569 {
570 
571 enum class DistributedType {
572  Local,
573  Ghost
574 };
575 
576 // Auxiliary type for compile-time dispatch of local/ghost mesh access
577 template<DistributedType TDistributed> struct MeshAccess
578 {
579  constexpr static DistributedType Value = TDistributed;
580 };
581 
582 enum class OperationType {
583  Replace,
584  SumValues,
585  MinValues,
586  AbsMinValues,
587  MaxValues,
588  AbsMaxValues,
589  OrAccessedFlags,
590  AndAccessedFlags,
591  ReplaceAccessedFlags
592 };
593 
594 // Auxiliary type for compile-time dispatch of the reduction operation in data transfer methods
595 template<OperationType TOperation> struct Operation
596 {
597  constexpr static OperationType Value = TOperation;
598 };
599 
600 public:
603 
604 
608 
611 
613 
615 
617 
619 
621 
623 
625 
627 
629 
631 
634 
640 
646 
654 
660 
666 
674 
680 
686 
689 
695 
701 
705 
707  KRATOS_DEPRECATED_MESSAGE("This constructor is deprecated, please use the one that accepts a DataCommunicator") MPICommunicator(VariablesList* Variables_list) : BaseType(DataCommunicator::GetDefault()), mpVariables_list(Variables_list)
708  {}
709 
711 
714  MPICommunicator(VariablesList* pVariablesList, const DataCommunicator& rDataCommunicator)
715  : BaseType(rDataCommunicator)
716  , mpVariables_list(pVariablesList)
717  {
718  KRATOS_ERROR_IF_NOT(rDataCommunicator.IsDistributed()) << "Trying to create an MPICommunicator with a non-distributed DataCommunicator!" << std::endl;
719  }
720 
722 
724  : BaseType(rOther)
725  , mpVariables_list(rOther.mpVariables_list)
726  {}
727 
728  using BaseType::Create;
729 
730  Communicator::Pointer Create(const DataCommunicator& rDataCommunicator) const override
731  {
732  KRATOS_TRY
733 
734  return Kratos::make_shared<MPICommunicator>(mpVariables_list, rDataCommunicator);
735 
736  KRATOS_CATCH("")
737  }
738 
740  ~MPICommunicator() override = default;
741 
745 
747  MPICommunicator & operator=(MPICommunicator const& rOther) = delete;
748 
752 
753  bool IsDistributed() const override
754  {
755  return true;
756  }
757 
761 
763  {
764  constexpr MeshAccess<DistributedType::Local> local_meshes;
765  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
766  constexpr Operation<OperationType::Replace> replace;
767  MPIInternals::NodalSolutionStepDataAccess nodal_solution_step_access;
768 
769  TransferDistributedValuesUnknownSize(local_meshes, ghost_meshes, nodal_solution_step_access, replace);
770 
771  return true;
772  }
773 
774  bool SynchronizeDofs() override
775  {
776  constexpr MeshAccess<DistributedType::Local> local_meshes;
777  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
778  constexpr Operation<OperationType::Replace> replace;
779  MPIInternals::DofIdAccess dof_id_access;
780 
781  TransferDistributedValues(local_meshes, ghost_meshes, dof_id_access, replace);
782 
783  return true;
784  }
785 
786  bool SynchronizeVariable(Variable<int> const& rThisVariable) override
787  {
788  MPIInternals::NodalSolutionStepValueAccess<int> solution_step_value_access(rThisVariable);
789  SynchronizeFixedSizeValues(solution_step_value_access);
790  return true;
791  }
792 
793  bool SynchronizeVariable(Variable<double> const& rThisVariable) override
794  {
795  MPIInternals::NodalSolutionStepValueAccess<double> solution_step_value_access(rThisVariable);
796  SynchronizeFixedSizeValues(solution_step_value_access);
797  return true;
798  }
799 
800  bool SynchronizeVariable(Variable<bool> const& rThisVariable) override
801  {
802  MPIInternals::NodalSolutionStepValueAccess<bool> solution_step_value_access(rThisVariable);
803  SynchronizeFixedSizeValues(solution_step_value_access);
804  return true;
805  }
806 
807  bool SynchronizeVariable(Variable<array_1d<double, 3 > > const& rThisVariable) override
808  {
809  MPIInternals::NodalSolutionStepValueAccess<array_1d<double,3>> solution_step_value_access(rThisVariable);
810  SynchronizeFixedSizeValues(solution_step_value_access);
811  return true;
812  }
813 
814  bool SynchronizeVariable(Variable<array_1d<double, 4 > > const& rThisVariable) override
815  {
816  MPIInternals::NodalSolutionStepValueAccess<array_1d<double,4>> solution_step_value_access(rThisVariable);
817  SynchronizeFixedSizeValues(solution_step_value_access);
818  return true;
819  }
820 
821  bool SynchronizeVariable(Variable<array_1d<double, 6 > > const& rThisVariable) override
822  {
823  MPIInternals::NodalSolutionStepValueAccess<array_1d<double,6>> solution_step_value_access(rThisVariable);
824  SynchronizeFixedSizeValues(solution_step_value_access);
825  return true;
826  }
827 
828  bool SynchronizeVariable(Variable<array_1d<double, 9 > > const& rThisVariable) override
829  {
830  MPIInternals::NodalSolutionStepValueAccess<array_1d<double,9>> solution_step_value_access(rThisVariable);
831  SynchronizeFixedSizeValues(solution_step_value_access);
832  return true;
833  }
834 
835  bool SynchronizeVariable(Variable<Vector> const& rThisVariable) override
836  {
837  MPIInternals::NodalSolutionStepValueAccess<Vector> solution_step_value_access(rThisVariable);
838  SynchronizeDynamicVectorValues(solution_step_value_access);
839  return true;
840  }
841 
842  bool SynchronizeVariable(Variable<Matrix> const& rThisVariable) override
843  {
844  MPIInternals::NodalSolutionStepValueAccess<Matrix> solution_step_value_access(rThisVariable);
845  SynchronizeDynamicMatrixValues(solution_step_value_access);
846  return true;
847  }
848 
849  bool SynchronizeVariable(Variable<Quaternion<double>> const& rThisVariable) override
850  {
851  MPIInternals::NodalSolutionStepValueAccess<Quaternion<double>> solution_step_value_access(rThisVariable);
852  SynchronizeFixedSizeValues(solution_step_value_access);
853  return true;
854  }
855 
856  bool SynchronizeNonHistoricalVariable(Variable<int> const& rThisVariable) override
857  {
858  MPIInternals::NodalDataAccess<int> nodal_data_access(rThisVariable);
859  SynchronizeFixedSizeValues(nodal_data_access);
860  return true;
861  }
862 
863  bool SynchronizeNonHistoricalVariable(Variable<double> const& rThisVariable) override
864  {
865  MPIInternals::NodalDataAccess<double> nodal_data_access(rThisVariable);
866  SynchronizeFixedSizeValues(nodal_data_access);
867  return true;
868  }
869 
870  bool SynchronizeNonHistoricalVariable(Variable<bool> const& rThisVariable) override
871  {
872  MPIInternals::NodalDataAccess<bool> nodal_data_access(rThisVariable);
873  SynchronizeFixedSizeValues(nodal_data_access);
874  return true;
875  }
876 
877  bool SynchronizeNonHistoricalVariable(Variable<array_1d<double, 3 > > const& rThisVariable) override
878  {
879  MPIInternals::NodalDataAccess<array_1d<double,3>> nodal_data_access(rThisVariable);
880  SynchronizeFixedSizeValues(nodal_data_access);
881  return true;
882  }
883 
884  bool SynchronizeNonHistoricalVariable(Variable<array_1d<double, 4 > > const& rThisVariable) override
885  {
886  MPIInternals::NodalDataAccess<array_1d<double,4>> nodal_data_access(rThisVariable);
887  SynchronizeFixedSizeValues(nodal_data_access);
888  return true;
889  }
890 
891  bool SynchronizeNonHistoricalVariable(Variable<array_1d<double, 6 > > const& rThisVariable) override
892  {
893  MPIInternals::NodalDataAccess<array_1d<double,6>> nodal_data_access(rThisVariable);
894  SynchronizeFixedSizeValues(nodal_data_access);
895  return true;
896  }
897 
898  bool SynchronizeNonHistoricalVariable(Variable<array_1d<double, 9 > > const& rThisVariable) override
899  {
900  MPIInternals::NodalDataAccess<array_1d<double,9>> nodal_data_access(rThisVariable);
901  SynchronizeFixedSizeValues(nodal_data_access);
902  return true;
903  }
904 
905  bool SynchronizeNonHistoricalVariable(Variable<Vector> const& rThisVariable) override
906  {
907  MPIInternals::NodalDataAccess<Vector> nodal_data_access(rThisVariable);
908  SynchronizeDynamicVectorValues(nodal_data_access);
909  return true;
910  }
911 
912  bool SynchronizeNonHistoricalVariable(Variable<Matrix> const& rThisVariable) override
913  {
914  MPIInternals::NodalDataAccess<Matrix> nodal_data_access(rThisVariable);
915  SynchronizeDynamicMatrixValues(nodal_data_access);
916  return true;
917  }
918 
919  bool SynchronizeNonHistoricalVariable(Variable<Quaternion<double>> const& rThisVariable) override
920  {
921  MPIInternals::NodalDataAccess<Quaternion<double>> nodal_data_access(rThisVariable);
922  SynchronizeFixedSizeValues(nodal_data_access);
923  return true;
924  }
925 
926  bool SynchronizeCurrentDataToMax(Variable<double> const& ThisVariable) override
927  {
928  constexpr MeshAccess<DistributedType::Local> local_meshes;
929  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
930  constexpr Operation<OperationType::Replace> replace;
931  constexpr Operation<OperationType::MaxValues> max;
932  MPIInternals::NodalSolutionStepValueAccess<double> nodal_solution_step_access(ThisVariable);
933 
934  // Calculate max on owner rank
935  TransferDistributedValues(ghost_meshes, local_meshes, nodal_solution_step_access, max);
936 
937  // Synchronize result on ghost copies
938  TransferDistributedValues(local_meshes, ghost_meshes, nodal_solution_step_access, replace);
939 
940  return true;
941  }
942 
943  bool SynchronizeNonHistoricalDataToMax(Variable<double> const& ThisVariable) override
944  {
945  constexpr MeshAccess<DistributedType::Local> local_meshes;
946  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
947  constexpr Operation<OperationType::Replace> replace;
948  constexpr Operation<OperationType::MaxValues> max;
949  MPIInternals::NodalDataAccess<double> nodal_data_access(ThisVariable);
950 
951  // Calculate max on owner rank
952  TransferDistributedValues(ghost_meshes, local_meshes, nodal_data_access, max);
953 
954  // Synchronize result on ghost copies
955  TransferDistributedValues(local_meshes, ghost_meshes, nodal_data_access, replace);
956 
957  return true;
958  }
959 
960  bool SynchronizeCurrentDataToAbsMax(Variable<double> const& ThisVariable) override
961  {
962  constexpr MeshAccess<DistributedType::Local> local_meshes;
963  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
964  constexpr Operation<OperationType::Replace> replace;
965  constexpr Operation<OperationType::AbsMaxValues> max;
966  MPIInternals::NodalSolutionStepValueAccess<double> nodal_solution_step_access(ThisVariable);
967 
968  // Calculate max on owner rank
969  TransferDistributedValues(ghost_meshes, local_meshes, nodal_solution_step_access, max);
970 
971  // Synchronize result on ghost copies
972  TransferDistributedValues(local_meshes, ghost_meshes, nodal_solution_step_access, replace);
973 
974  return true;
975  }
976 
977  bool SynchronizeNonHistoricalDataToAbsMax(Variable<double> const& ThisVariable) override
978  {
979  constexpr MeshAccess<DistributedType::Local> local_meshes;
980  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
981  constexpr Operation<OperationType::Replace> replace;
982  constexpr Operation<OperationType::AbsMaxValues> max;
983  MPIInternals::NodalDataAccess<double> nodal_data_access(ThisVariable);
984 
985  // Calculate max on owner rank
986  TransferDistributedValues(ghost_meshes, local_meshes, nodal_data_access, max);
987 
988  // Synchronize result on ghost copies
989  TransferDistributedValues(local_meshes, ghost_meshes, nodal_data_access, replace);
990 
991  return true;
992  }
993 
994  bool SynchronizeCurrentDataToMin(Variable<double> const& ThisVariable) override
995  {
996  constexpr MeshAccess<DistributedType::Local> local_meshes;
997  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
998  constexpr Operation<OperationType::Replace> replace;
999  constexpr Operation<OperationType::MinValues> min;
1000  MPIInternals::NodalSolutionStepValueAccess<double> nodal_solution_step_access(ThisVariable);
1001 
1002  // Calculate min on owner rank
1003  TransferDistributedValues(ghost_meshes, local_meshes, nodal_solution_step_access, min);
1004 
1005  // Synchronize result on ghost copies
1006  TransferDistributedValues(local_meshes, ghost_meshes, nodal_solution_step_access, replace);
1007 
1008  return true;
1009  }
1010 
1011  bool SynchronizeNonHistoricalDataToMin(Variable<double> const& ThisVariable) override
1012  {
1013  constexpr MeshAccess<DistributedType::Local> local_meshes;
1014  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1015  constexpr Operation<OperationType::Replace> replace;
1016  constexpr Operation<OperationType::MinValues> min;
1017  MPIInternals::NodalDataAccess<double> nodal_data_access(ThisVariable);
1018 
1019  // Calculate min on owner rank
1020  TransferDistributedValues(ghost_meshes, local_meshes, nodal_data_access, min);
1021 
1022  // Synchronize result on ghost copies
1023  TransferDistributedValues(local_meshes, ghost_meshes, nodal_data_access, replace);
1024 
1025  return true;
1026  }
1027 
1028  bool SynchronizeCurrentDataToAbsMin(Variable<double> const& ThisVariable) override
1029  {
1030  constexpr MeshAccess<DistributedType::Local> local_meshes;
1031  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1032  constexpr Operation<OperationType::Replace> replace;
1033  constexpr Operation<OperationType::AbsMinValues> min;
1034  MPIInternals::NodalSolutionStepValueAccess<double> nodal_solution_step_access(ThisVariable);
1035 
1036  // Calculate min on owner rank
1037  TransferDistributedValues(ghost_meshes, local_meshes, nodal_solution_step_access, min);
1038 
1039  // Synchronize result on ghost copies
1040  TransferDistributedValues(local_meshes, ghost_meshes, nodal_solution_step_access, replace);
1041 
1042  return true;
1043  }
1044 
1045  bool SynchronizeNonHistoricalDataToAbsMin(Variable<double> const& ThisVariable) override
1046  {
1047  constexpr MeshAccess<DistributedType::Local> local_meshes;
1048  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1049  constexpr Operation<OperationType::Replace> replace;
1050  constexpr Operation<OperationType::AbsMinValues> min;
1051  MPIInternals::NodalDataAccess<double> nodal_data_access(ThisVariable);
1052 
1053  // Calculate min on owner rank
1054  TransferDistributedValues(ghost_meshes, local_meshes, nodal_data_access, min);
1055 
1056  // Synchronize result on ghost copies
1057  TransferDistributedValues(local_meshes, ghost_meshes, nodal_data_access, replace);
1058 
1059  return true;
1060  }
1061 
1062  bool AssembleCurrentData(Variable<int> const& ThisVariable) override
1063  {
1064  MPIInternals::NodalSolutionStepValueAccess<int> solution_step_access(ThisVariable);
1065  AssembleFixedSizeValues(solution_step_access);
1066  return true;
1067  }
1068 
1069  bool AssembleCurrentData(Variable<double> const& ThisVariable) override
1070  {
1071  MPIInternals::NodalSolutionStepValueAccess<double> solution_step_access(ThisVariable);
1072  AssembleFixedSizeValues(solution_step_access);
1073  return true;
1074  }
1075 
1076  bool AssembleCurrentData(Variable<array_1d<double, 3 > > const& ThisVariable) override
1077  {
1078  MPIInternals::NodalSolutionStepValueAccess<array_1d<double,3>> solution_step_access(ThisVariable);
1079  AssembleFixedSizeValues(solution_step_access);
1080  return true;
1081  }
1082 
1083  bool AssembleCurrentData(Variable<Vector> const& ThisVariable) override
1084  {
1085  MPIInternals::NodalSolutionStepValueAccess<Vector> solution_step_access(ThisVariable);
1086  AssembleDynamicVectorValues(solution_step_access);
1087  return true;
1088  }
1089 
1090  bool AssembleCurrentData(Variable<Matrix> const& ThisVariable) override
1091  {
1092  MPIInternals::NodalSolutionStepValueAccess<Matrix> solution_step_access(ThisVariable);
1093  AssembleDynamicMatrixValues(solution_step_access);
1094  return true;
1095  }
1096 
1097  bool AssembleNonHistoricalData(Variable<int> const& ThisVariable) override
1098  {
1099  MPIInternals::NodalDataAccess<int> nodal_data_access(ThisVariable);
1100  AssembleFixedSizeValues(nodal_data_access);
1101  return true;
1102  }
1103 
1104  bool AssembleNonHistoricalData(Variable<double> const& ThisVariable) override
1105  {
1106  MPIInternals::NodalDataAccess<double> nodal_data_access(ThisVariable);
1107  AssembleFixedSizeValues(nodal_data_access);
1108  return true;
1109  }
1110 
1111  bool AssembleNonHistoricalData(Variable<array_1d<double, 3 > > const& ThisVariable) override
1112  {
1113  MPIInternals::NodalDataAccess<array_1d<double,3>> nodal_data_access(ThisVariable);
1114  AssembleFixedSizeValues(nodal_data_access);
1115  return true;
1116  }
1117 
1118  bool AssembleNonHistoricalData(Variable<DenseVector<array_1d<double,3> > > const& ThisVariable) override
1119  {
1120  MPIInternals::NodalDataAccess<DenseVector<array_1d<double,3>>> nodal_data_access(ThisVariable);
1121  AssembleDynamicVectorValues(nodal_data_access);
1122  return true;
1123  }
1124 
1125  bool AssembleNonHistoricalData(Variable<Vector> const& ThisVariable) override
1126  {
1127  MPIInternals::NodalDataAccess<Vector> nodal_data_access(ThisVariable);
1128  AssembleDynamicVectorValues(nodal_data_access);
1129  return true;
1130  }
1131 
1132  bool AssembleNonHistoricalData(Variable<Matrix> const& ThisVariable) override
1133  {
1134  MPIInternals::NodalDataAccess<Matrix> nodal_data_access(ThisVariable);
1135  AssembleDynamicMatrixValues(nodal_data_access);
1136  return true;
1137  }
1138 
1140 
1142  {
1143  MPIInternals::ElementalDataAccess<int> elemental_data_access(ThisVariable);
1144  SynchronizeFixedSizeValues(elemental_data_access);
1145  return true;
1146  }
1147 
1149  {
1150  MPIInternals::ElementalDataAccess<double> elemental_data_access(ThisVariable);
1151  SynchronizeFixedSizeValues(elemental_data_access);
1152  return true;
1153  }
1154 
1156  {
1157  MPIInternals::ElementalDataAccess<array_1d<double,3>> elemental_data_access(ThisVariable);
1158  SynchronizeFixedSizeValues(elemental_data_access);
1159  return true;
1160  }
1161 
1163  {
1164  MPIInternals::ElementalDataAccess<DenseVector<array_1d<double,3>>> elemental_data_access(ThisVariable);
1165  AssembleDynamicVectorValues(elemental_data_access);
1166  return true;
1167  }
1168 
1170  {
1171  MPIInternals::ElementalDataAccess<DenseVector<int>> elemental_data_access(ThisVariable);
1172  AssembleDynamicVectorValues(elemental_data_access);
1173  return true;
1174  }
1175 
1177  {
1178  MPIInternals::ElementalDataAccess<Vector> elemental_data_access(ThisVariable);
1179  SynchronizeDynamicVectorValues(elemental_data_access);
1180  return true;
1181  }
1182 
1184  {
1185  MPIInternals::ElementalDataAccess<Matrix> elemental_data_access(ThisVariable);
1186  SynchronizeDynamicMatrixValues(elemental_data_access);
1187  return true;
1188  }
1189 
1191 
1197  bool TransferObjects(std::vector<NodesContainerType>& SendObjects, std::vector<NodesContainerType>& RecvObjects) override
1198  {
1199  AsyncSendAndReceiveObjects<NodesContainerType>(SendObjects,RecvObjects);
1200  return true;
1201  }
1202 
1208  bool TransferObjects(std::vector<ElementsContainerType>& SendObjects, std::vector<ElementsContainerType>& RecvObjects) override
1209  {
1210  AsyncSendAndReceiveObjects<ElementsContainerType>(SendObjects,RecvObjects);
1211  return true;
1212  }
1213 
1219  bool TransferObjects(std::vector<ConditionsContainerType>& SendObjects, std::vector<ConditionsContainerType>& RecvObjects) override
1220  {
1221  AsyncSendAndReceiveObjects<ConditionsContainerType>(SendObjects,RecvObjects);
1222  return true;
1223  }
1224 
1230  bool TransferObjects(std::vector<NodesContainerType>& SendObjects, std::vector<NodesContainerType>& RecvObjects,Kratos::Serializer& particleSerializer) override
1231  {
1232  AsyncSendAndReceiveObjects<NodesContainerType>(SendObjects,RecvObjects);
1233  return true;
1234  }
1235 
1241  bool TransferObjects(std::vector<ElementsContainerType>& SendObjects, std::vector<ElementsContainerType>& RecvObjects,Kratos::Serializer& particleSerializer) override
1242  {
1243  AsyncSendAndReceiveObjects<ElementsContainerType>(SendObjects,RecvObjects);
1244  return true;
1245  }
1246 
1252  bool TransferObjects(std::vector<ConditionsContainerType>& SendObjects, std::vector<ConditionsContainerType>& RecvObjects,Kratos::Serializer& particleSerializer) override
1253  {
1254  AsyncSendAndReceiveObjects<ConditionsContainerType>(SendObjects,RecvObjects);
1255  return true;
1256  }
1257 
1262  bool SynchronizeOrNodalFlags(const Flags& TheFlags) override
1263  {
1264  constexpr MeshAccess<DistributedType::Local> local_meshes;
1265  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1266  MPIInternals::NodalFlagsAccess nodal_flag_access(TheFlags);
1267  constexpr Operation<OperationType::OrAccessedFlags> or_accessed;
1268  constexpr Operation<OperationType::ReplaceAccessedFlags> replace_accessed;
1269 
1270  TransferDistributedValues(ghost_meshes, local_meshes, nodal_flag_access, or_accessed);
1271 
1272  TransferDistributedValues(local_meshes, ghost_meshes, nodal_flag_access, replace_accessed);
1273  return true;
1274  }
1275 
1280  bool SynchronizeAndNodalFlags(const Flags& TheFlags) override
1281  {
1282  constexpr MeshAccess<DistributedType::Local> local_meshes;
1283  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1284  MPIInternals::NodalFlagsAccess nodal_flag_access(TheFlags);
1285  constexpr Operation<OperationType::AndAccessedFlags> and_accessed;
1286  constexpr Operation<OperationType::ReplaceAccessedFlags> replace_accessed;
1287 
1288  TransferDistributedValues(ghost_meshes, local_meshes, nodal_flag_access, and_accessed);
1289 
1290  TransferDistributedValues(local_meshes, ghost_meshes, nodal_flag_access, replace_accessed);
1291  return true;
1292  }
1293 
1294  bool SynchronizeNodalFlags() override
1295  {
1296  constexpr MeshAccess<DistributedType::Local> local_meshes;
1297  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1298  MPIInternals::NodalFlagsAccess nodal_flags_access(Flags::AllDefined());
1299  constexpr Operation<OperationType::Replace> replace;
1300 
1301  TransferDistributedValues(local_meshes, ghost_meshes, nodal_flags_access, replace);
1302  return true;
1303  }
1304 
1306  {
1307  constexpr MeshAccess<DistributedType::Local> local_meshes;
1308  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1309  MPIInternals::ElementalFlagsAccess elemental_flags_access(Flags::AllDefined());
1310  constexpr Operation<OperationType::Replace> replace;
1311 
1312  TransferDistributedValues(local_meshes, ghost_meshes, elemental_flags_access, replace);
1313  return true;
1314  }
1315 
1317 
1321 
1322 
1326 
1327 
1331 
1333 
1334  std::string Info() const override
1335  {
1336  return "MPICommunicator";
1337  }
1338 
1342 
1343 
1345 
1346 protected:
1349 
1350 
1354 
1355 
1359 
1360 
1364 
1365 
1369 
1370 
1374 
1375 
1379 
1380 
1382 
1383 private:
1386 
1387 
1391 
1392  VariablesList* mpVariables_list;
1393 
1397 
1398 
1402 
1403  void PrintNodesId()
1404  {
1405  NeighbourIndicesContainerType& neighbours_indices = NeighbourIndices();
1406 
1407  int nproc = mrDataCommunicator.Size();
1408  int rank = mrDataCommunicator.Rank();
1409 
1411  for (int proc_id = 0; proc_id < nproc; proc_id++)
1412  {
1413  if (proc_id == rank)
1414  {
1415 
1416  for (int i_color = 0; i_color < static_cast<int>(neighbours_indices.size()); i_color++)
1417  {
1418  if ((neighbours_indices[i_color]) >= 0)
1419  {
1420  NodesContainerType& r_local_nodes = LocalMesh(i_color).Nodes();
1421  NodesContainerType& r_ghost_nodes = GhostMesh(i_color).Nodes();
1422  std::string tag = "Local nodes in rank ";
1423  PrintNodesId(r_local_nodes, tag, i_color);
1424  tag = "Ghost nodes in rank ";
1425  PrintNodesId(r_ghost_nodes, tag, i_color);
1426  tag = "Interface nodes in rank ";
1427  PrintNodesId(InterfaceMesh(i_color).Nodes(), tag, i_color);
1428 
1429  }
1430  }
1431  }
1433  }
1434  }
1435 
1436  template<class TNodesArrayType>
1437  void PrintNodesId(TNodesArrayType& rNodes, const std::string& Tag, int color)
1438  {
1439  int rank = mrDataCommunicator.Rank();
1440  std::cout << Tag << rank << " with color " << color << ":";
1441  for (typename TNodesArrayType::iterator i_node = rNodes.begin(); i_node != rNodes.end(); i_node++)
1442  std::cout << i_node->Id() << ", ";
1443 
1444  std::cout << std::endl;
1445  }
1446 
1447  template<class TObjectType>
1448  bool AsyncSendAndReceiveObjects(std::vector<TObjectType>& SendObjects, std::vector<TObjectType>& RecvObjects)
1449  {
1450  int mpi_rank = mrDataCommunicator.Rank();
1451  int mpi_size = mrDataCommunicator.Size();
1452 
1454 
1455  int * msgSendSize = new int[mpi_size];
1456  int * msgRecvSize = new int[mpi_size];
1457 
1458  char ** message = new char * [mpi_size];
1459  char ** mpi_send_buffer = new char * [mpi_size];
1460 
1461  for(int i = 0; i < mpi_size; i++)
1462  {
1463  msgSendSize[i] = 0;
1464  msgRecvSize[i] = 0;
1465  }
1466 
1467  for(int i = 0; i < mpi_size; i++)
1468  {
1469  if(mpi_rank != i)
1470  {
1471  Kratos::MpiSerializer serializer;
1472 
1473  serializer.save("VariableList",mpVariables_list);
1474  serializer.save("ObjectList",SendObjects[i].GetContainer());
1475 
1476  std::stringstream * stream = (std::stringstream *)serializer.pGetBuffer();
1477  const std::string & stream_str = stream->str();
1478  const char * cstr = stream_str.c_str();
1479 
1480  msgSendSize[i] = sizeof(char) * (stream_str.size()+1);
1481  mpi_send_buffer[i] = (char *)malloc(msgSendSize[i]);
1482  memcpy(mpi_send_buffer[i],cstr,msgSendSize[i]);
1483  }
1484  }
1485 
1486  MPI_Alltoall(msgSendSize,1,MPI_INT,msgRecvSize,1,MPI_INT,comm);
1487 
1488  int NumberOfCommunicationEvents = 0;
1489  int NumberOfCommunicationEventsIndex = 0;
1490 
1491  for(int j = 0; j < mpi_size; j++)
1492  {
1493  if(j != mpi_rank && msgRecvSize[j]) NumberOfCommunicationEvents++;
1494  if(j != mpi_rank && msgSendSize[j]) NumberOfCommunicationEvents++;
1495  }
1496 
1497  MPI_Request * reqs = new MPI_Request[NumberOfCommunicationEvents];
1498  MPI_Status * stats = new MPI_Status[NumberOfCommunicationEvents];
1499 
1500  //Set up all receive and send events
1501  for(int i = 0; i < mpi_size; i++)
1502  {
1503  if(i != mpi_rank && msgRecvSize[i])
1504  {
1505  message[i] = (char *)malloc(sizeof(char) * msgRecvSize[i]);
1506 
1507  MPI_Irecv(message[i],msgRecvSize[i],MPI_CHAR,i,0,comm,&reqs[NumberOfCommunicationEventsIndex++]);
1508  }
1509 
1510  if(i != mpi_rank && msgSendSize[i])
1511  {
1512  MPI_Isend(mpi_send_buffer[i],msgSendSize[i],MPI_CHAR,i,0,comm,&reqs[NumberOfCommunicationEventsIndex++]);
1513  }
1514  }
1515 
1516  //wait untill all communications finish
1517  int err = MPI_Waitall(NumberOfCommunicationEvents, reqs, stats);
1518 
1519  KRATOS_ERROR_IF(err != MPI_SUCCESS) << "Error in MPICommunicator asynchronous data transfer" << std::endl;
1520 
1522 
1523  for(int i = 0; i < mpi_size; i++)
1524  {
1525  if (i != mpi_rank && msgRecvSize[i])
1526  {
1527  Kratos::MpiSerializer serializer;
1528  std::stringstream * serializer_buffer;
1529 
1530  serializer_buffer = (std::stringstream *)serializer.pGetBuffer();
1531  serializer_buffer->write(message[i], msgRecvSize[i]);
1532 
1533  VariablesList* tmp_mpVariables_list = NULL;
1534 
1535  serializer.load("VariableList",tmp_mpVariables_list);
1536 
1537  if(tmp_mpVariables_list != NULL)
1538  delete tmp_mpVariables_list;
1539  tmp_mpVariables_list = mpVariables_list;
1540 
1541  serializer.load("ObjectList",RecvObjects[i].GetContainer());
1542  }
1543 
1545  }
1546 
1547  // Free buffers
1548  for(int i = 0; i < mpi_size; i++)
1549  {
1550  if(msgRecvSize[i])
1551  free(message[i]);
1552 
1553  if(msgSendSize[i])
1554  free(mpi_send_buffer[i]);
1555  }
1556 
1557  delete [] reqs;
1558  delete [] stats;
1559 
1560  delete [] message;
1561  delete [] mpi_send_buffer;
1562 
1563  delete [] msgSendSize;
1564  delete [] msgRecvSize;
1565 
1566  return true;
1567  }
1568 
1569  template<class TDatabaseAccess>
1570  void SynchronizeFixedSizeValues(TDatabaseAccess& rVariableAccess)
1571  {
1572  constexpr MeshAccess<DistributedType::Local> local_meshes;
1573  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1574  constexpr Operation<OperationType::Replace> replace;
1575 
1576  TransferDistributedValues(local_meshes, ghost_meshes, rVariableAccess, replace);
1577  }
1578 
1579  template<class TDatabaseAccess>
1580  void SynchronizeDynamicVectorValues(TDatabaseAccess& rVariableAccess)
1581  {
1582  constexpr MeshAccess<DistributedType::Local> local_meshes;
1583  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1584  constexpr Operation<OperationType::Replace> replace;
1585 
1586  // Communicate vector sizes to ghost copies
1587  MatchDynamicVectorSizes(local_meshes, ghost_meshes, rVariableAccess);
1588 
1589  // Synchronize values on ghost copies
1590  TransferDistributedValues(local_meshes, ghost_meshes, rVariableAccess, replace);
1591  }
1592 
1593  template<class TDatabaseAccess>
1594  void SynchronizeDynamicMatrixValues(TDatabaseAccess& rVariableAccess)
1595  {
1596  constexpr MeshAccess<DistributedType::Local> local_meshes;
1597  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1598  constexpr Operation<OperationType::Replace> replace;
1599 
1600  // Communicate matrix sizes to ghost copies
1601  MatchDynamicMatrixSizes(local_meshes, ghost_meshes, rVariableAccess);
1602 
1603  // Synchronize values on ghost copies
1604  TransferDistributedValues(local_meshes, ghost_meshes, rVariableAccess, replace);
1605  }
1606 
1607  template<class TDatabaseAccess>
1608  void AssembleFixedSizeValues(TDatabaseAccess& rVariableAccess)
1609  {
1610  constexpr MeshAccess<DistributedType::Local> local_meshes;
1611  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1612  constexpr Operation<OperationType::Replace> replace;
1613  constexpr Operation<OperationType::SumValues> sum;
1614 
1615  // Assemble results on owner rank
1616  TransferDistributedValues(ghost_meshes, local_meshes, rVariableAccess, sum);
1617 
1618  // Synchronize result on ghost copies
1619  TransferDistributedValues(local_meshes, ghost_meshes, rVariableAccess, replace);
1620  }
1621 
1622  template<class TDatabaseAccess>
1623  void AssembleDynamicVectorValues(TDatabaseAccess& rVariableAccess)
1624  {
1625  constexpr MeshAccess<DistributedType::Local> local_meshes;
1626  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1627  constexpr Operation<OperationType::Replace> replace;
1628  constexpr Operation<OperationType::SumValues> sum;
1629 
1630  // Combine vector sizes on owner rank
1631  MatchDynamicVectorSizes(ghost_meshes, local_meshes, rVariableAccess);
1632 
1633  // Communicate vector sizes to ghost copies
1634  MatchDynamicVectorSizes(local_meshes, ghost_meshes, rVariableAccess);
1635 
1636  // From this point on, we can assume buffer sizes will always match for all ranks
1637 
1638  // Assemble results on owner rank
1639  TransferDistributedValues(ghost_meshes, local_meshes, rVariableAccess, sum);
1640 
1641  // Synchronize result on ghost copies
1642  TransferDistributedValues(local_meshes, ghost_meshes, rVariableAccess, replace);
1643  }
1644 
1645  template<class TDatabaseAccess>
1646  void AssembleDynamicMatrixValues(TDatabaseAccess& rVariableAccess)
1647  {
1648  constexpr MeshAccess<DistributedType::Local> local_meshes;
1649  constexpr MeshAccess<DistributedType::Ghost> ghost_meshes;
1650  constexpr Operation<OperationType::Replace> replace;
1651  constexpr Operation<OperationType::SumValues> sum;
1652 
1653  // Combine matrix sizes on owner rank
1654  MatchDynamicMatrixSizes(ghost_meshes, local_meshes, rVariableAccess);
1655 
1656  // Communicate matrix sizes to ghost copies
1657  MatchDynamicMatrixSizes(local_meshes, ghost_meshes, rVariableAccess);
1658 
1659  // From this point on, we can assume buffer sizes will always match for all ranks
1660 
1661  // Assemble results on owner rank
1662  TransferDistributedValues(ghost_meshes, local_meshes, rVariableAccess, sum);
1663 
1664  // Synchronize result on ghost copies
1665  TransferDistributedValues(local_meshes, ghost_meshes, rVariableAccess, replace);
1666  }
1667 
1668  MeshType& GetMesh(IndexType Color, const MeshAccess<DistributedType::Local>)
1669  {
1670  return LocalMesh(Color);
1671  }
1672 
1673  MeshType& GetMesh(IndexType Color, const MeshAccess<DistributedType::Ghost>)
1674  {
1675  return GhostMesh(Color);
1676  }
1677 
1678  template<class TDatabaseAccess>
1679  std::size_t ReduceValues(
1680  const typename TDatabaseAccess::SendType* pBuffer,
1681  TDatabaseAccess& rAccess,
1682  typename TDatabaseAccess::IteratorType ContainerIterator,
1683  Operation<OperationType::Replace>)
1684  {
1685  // Replace the value by reading the sent buffer in place.
1686  // Note that dynamic types are assumed to already have the
1687  // correct size (communicated in advance, if necessary).
1688  using ValueType = typename TDatabaseAccess::ValueType;
1689  auto& r_destination = rAccess.GetValue(ContainerIterator);
1690  MPIInternals::SendTools<ValueType>::ReadBuffer(pBuffer, r_destination);
1691 
1693  }
1694 
1695  template<class TDatabaseAccess>
1696  std::size_t ReduceValues(
1697  const typename TDatabaseAccess::SendType* pBuffer,
1698  TDatabaseAccess& rAccess,
1699  typename TDatabaseAccess::IteratorType ContainerIterator,
1700  Operation<OperationType::SumValues>)
1701  {
1702  using ValueType = typename TDatabaseAccess::ValueType;
1703  ValueType& r_current = rAccess.GetValue(ContainerIterator);
1704  ValueType recv_value(r_current); // creating by copy to have the correct size in dynamic types
1705  MPIInternals::SendTools<ValueType>::ReadBuffer(pBuffer, recv_value);
1706  r_current += recv_value;
1707 
1709  }
1710 
1711  template<class TDatabaseAccess>
1712  std::size_t ReduceValues(
1713  const typename TDatabaseAccess::SendType* pBuffer,
1714  TDatabaseAccess& rAccess,
1715  typename TDatabaseAccess::IteratorType ContainerIterator,
1716  Operation<OperationType::MaxValues>)
1717  {
1718  using ValueType = typename TDatabaseAccess::ValueType;
1719  ValueType& r_current = rAccess.GetValue(ContainerIterator);
1720  ValueType recv_value(r_current); // creating by copy to have the correct size in dynamic types
1721  MPIInternals::SendTools<ValueType>::ReadBuffer(pBuffer, recv_value);
1722  if (recv_value > r_current) r_current = recv_value;
1723 
1725  }
1726 
1727  template<class TDatabaseAccess>
1728  std::size_t ReduceValues(
1729  const typename TDatabaseAccess::SendType* pBuffer,
1730  TDatabaseAccess& rAccess,
1731  typename TDatabaseAccess::IteratorType ContainerIterator,
1732  Operation<OperationType::AbsMaxValues>)
1733  {
1734  using ValueType = typename TDatabaseAccess::ValueType;
1735  ValueType& r_current = rAccess.GetValue(ContainerIterator);
1736  ValueType recv_value(r_current); // creating by copy to have the correct size in dynamic types
1737  MPIInternals::SendTools<ValueType>::ReadBuffer(pBuffer, recv_value);
1738  if (std::abs(recv_value) > std::abs(r_current)) r_current = recv_value;
1739 
1741  }
1742 
1743  template<class TDatabaseAccess>
1744  std::size_t ReduceValues(
1745  const typename TDatabaseAccess::SendType* pBuffer,
1746  TDatabaseAccess& rAccess,
1747  typename TDatabaseAccess::IteratorType ContainerIterator,
1748  Operation<OperationType::MinValues>)
1749  {
1750  using ValueType = typename TDatabaseAccess::ValueType;
1751  ValueType& r_current = rAccess.GetValue(ContainerIterator);
1752  ValueType recv_value(r_current); // creating by copy to have the correct size in dynamic types
1753  MPIInternals::SendTools<ValueType>::ReadBuffer(pBuffer, recv_value);
1754  if (recv_value < r_current) r_current = recv_value;
1755 
1757  }
1758 
1759  template<class TDatabaseAccess>
1760  std::size_t ReduceValues(
1761  const typename TDatabaseAccess::SendType* pBuffer,
1762  TDatabaseAccess& rAccess,
1763  typename TDatabaseAccess::IteratorType ContainerIterator,
1764  Operation<OperationType::AbsMinValues>)
1765  {
1766  using ValueType = typename TDatabaseAccess::ValueType;
1767  ValueType& r_current = rAccess.GetValue(ContainerIterator);
1768  ValueType recv_value(r_current); // creating by copy to have the correct size in dynamic types
1769  MPIInternals::SendTools<ValueType>::ReadBuffer(pBuffer, recv_value);
1770  if (std::abs(recv_value) < std::abs(r_current)) r_current = recv_value;
1771 
1773  }
1774 
1775  template<class TDatabaseAccess>
1776  std::size_t ReduceValues(
1777  const typename TDatabaseAccess::SendType* pBuffer,
1778  TDatabaseAccess& rAccess,
1779  typename TDatabaseAccess::IteratorType ContainerIterator,
1780  Operation<OperationType::AndAccessedFlags>)
1781  {
1782  using ValueType = typename TDatabaseAccess::ValueType;
1783  ValueType recv_value;
1784  MPIInternals::SendTools<ValueType>::ReadBuffer(pBuffer, recv_value);
1785  rAccess.GetValue(ContainerIterator) &= recv_value | ~rAccess.mrMask;
1786 
1788  }
1789 
1790  template<class TDatabaseAccess>
1791  std::size_t ReduceValues(
1792  const typename TDatabaseAccess::SendType* pBuffer,
1793  TDatabaseAccess& rAccess,
1794  typename TDatabaseAccess::IteratorType ContainerIterator,
1795  Operation<OperationType::OrAccessedFlags>)
1796  {
1797  using ValueType = typename TDatabaseAccess::ValueType;
1798  ValueType recv_value;
1799  MPIInternals::SendTools<ValueType>::ReadBuffer(pBuffer, recv_value);
1800  rAccess.GetValue(ContainerIterator) |= recv_value & rAccess.mrMask;
1801 
1803  }
1804 
1805  template<class TDatabaseAccess>
1806  std::size_t ReduceValues(
1807  const typename TDatabaseAccess::SendType* pBuffer,
1808  TDatabaseAccess& rAccess,
1809  typename TDatabaseAccess::IteratorType ContainerIterator,
1810  Operation<OperationType::ReplaceAccessedFlags>)
1811  {
1812  using ValueType = typename TDatabaseAccess::ValueType;
1813  ValueType recv_value;
1814  MPIInternals::SendTools<ValueType>::ReadBuffer(pBuffer, recv_value);
1815 
1816  ValueType& r_current = rAccess.GetValue(ContainerIterator);
1817  r_current.AssignFlags( (recv_value & rAccess.mrMask) | (r_current & ~rAccess.mrMask) );
1818 
1820  }
1821 
1822  template<
1823  typename TSourceAccess,
1824  typename TDestinationAccess,
1825  class TDatabaseAccess,
1826  typename TReductionOperation>
1827  void TransferDistributedValues(
1828  TSourceAccess SourceType,
1829  TDestinationAccess DestinationType,
1830  TDatabaseAccess& rAccess,
1831  TReductionOperation Reduction)
1832  {
1833  using DataType = typename TDatabaseAccess::ValueType;
1834  using BufferType = typename MPIInternals::SendTraits<DataType>::BufferType;
1835  int destination = 0;
1836 
1837  NeighbourIndicesContainerType& neighbour_indices = NeighbourIndices();
1838 
1839  BufferType send_values;
1840  BufferType recv_values;
1841 
1842  for (unsigned int i_color = 0; i_color < neighbour_indices.size(); i_color++)
1843  {
1844  if ( (destination = neighbour_indices[i_color]) >= 0)
1845  {
1846  MeshType& r_source_mesh = GetMesh(i_color, SourceType);
1847  AllocateBuffer(send_values, r_source_mesh, rAccess);
1848 
1849  MeshType& r_destination_mesh = GetMesh(i_color, DestinationType);
1850  AllocateBuffer(recv_values, r_destination_mesh, rAccess);
1851 
1852  if ( (send_values.size() == 0) && (recv_values.size() == 0) )
1853  {
1854  continue; // nothing to transfer, skip communication step
1855  }
1856 
1857  FillBuffer(send_values, r_source_mesh, rAccess);
1858 
1860  send_values, destination, i_color,
1861  recv_values, destination, i_color);
1862 
1863  UpdateValues(recv_values, r_destination_mesh, rAccess, Reduction);
1864  }
1865  }
1866  }
1867 
1868  template<
1869  typename TSourceAccess,
1870  typename TDestinationAccess,
1871  class TDatabaseAccess,
1872  typename TReductionOperation>
1873  void TransferDistributedValuesUnknownSize(
1874  TSourceAccess SourceType,
1875  TDestinationAccess DestinationType,
1876  TDatabaseAccess& rAccess,
1877  TReductionOperation Reduction)
1878  {
1879  using DataType = typename TDatabaseAccess::ValueType;
1880  using BufferType = typename MPIInternals::SendTraits<DataType>::BufferType;
1881  int destination = 0;
1882 
1883  NeighbourIndicesContainerType& neighbour_indices = NeighbourIndices();
1884 
1885  BufferType send_values;
1886  BufferType recv_values;
1887 
1888  for (unsigned int i_color = 0; i_color < neighbour_indices.size(); i_color++)
1889  {
1890  if ( (destination = neighbour_indices[i_color]) >= 0)
1891  {
1892  MeshType& r_source_mesh = GetMesh(i_color, SourceType);
1893  MeshType& r_destination_mesh = GetMesh(i_color, DestinationType);
1894 
1895  FillBuffer(send_values, r_source_mesh, rAccess);
1896 
1897  std::vector<int> send_size{(int)send_values.size()};
1898  std::vector<int> recv_size{0};
1899 
1901  send_size, destination, i_color,
1902  recv_size, destination, i_color);
1903 
1904  recv_values.resize(recv_size[0]);
1905 
1906  if ( (send_values.size() == 0) && (recv_values.size() == 0) )
1907  {
1908  continue; // nothing to transfer, skip communication step
1909  }
1910 
1912  send_values, destination, i_color,
1913  recv_values, destination, i_color);
1914 
1915  UpdateValues(recv_values, r_destination_mesh, rAccess, Reduction);
1916  }
1917  }
1918  }
1919 
1920  template<
1921  class TDatabaseAccess,
1922  typename TValue = typename TDatabaseAccess::ValueType,
1923  typename TSendType = typename MPIInternals::SendTraits<TValue>::SendType>
1924  void AllocateBuffer(std::vector<TSendType>& rBuffer, const MeshType& rSourceMesh, TDatabaseAccess& rAccess)
1925  {
1926  const std::size_t buffer_size = MPIInternals::BufferAllocation<TDatabaseAccess>::GetSendSize(rAccess, rSourceMesh);
1927 
1928  if (rBuffer.size() != buffer_size)
1929  {
1930  rBuffer.resize(buffer_size);
1931  }
1932  }
1933 
1934  template<
1935  class TDatabaseAccess,
1936  typename TValue = typename TDatabaseAccess::ValueType,
1937  typename TSendType = typename MPIInternals::SendTraits<TValue>::SendType>
1938  void FillBuffer(std::vector<TSendType>& rBuffer, MeshType& rSourceMesh, TDatabaseAccess& rAccess)
1939  {
1940  auto& r_container = rAccess.GetContainer(rSourceMesh);
1941  TSendType* p_buffer = rBuffer.data();
1942  std::size_t position = 0;
1943  for (auto iter = r_container.begin(); iter != r_container.end(); ++iter)
1944  {
1945  TValue& r_value = rAccess.GetValue(iter);
1946  MPIInternals::SendTools<TValue>::WriteBuffer(r_value, p_buffer + position);
1948  }
1949  }
1950 
1951  template<
1952  class TDatabaseAccess,
1953  typename TValue = typename TDatabaseAccess::ValueType>
1954  void FillBuffer(std::string& rBuffer, MeshType& rSourceMesh, TDatabaseAccess& rAccess)
1955  {
1956  StreamSerializer serializer;
1957  auto& r_container = rAccess.GetContainer(rSourceMesh);
1958 
1959  for (auto iter = r_container.begin(); iter != r_container.end(); ++iter)
1960  {
1961  TValue& r_value = rAccess.GetValue(iter);
1962  serializer.save("Value", r_value);
1963  }
1964 
1965  rBuffer = serializer.GetStringRepresentation();
1966  }
1967 
1968  template<
1969  class TDatabaseAccess,
1970  typename TReductionOperation,
1971  typename TValue = typename TDatabaseAccess::ValueType,
1972  typename TSendType = typename MPIInternals::SendTraits<TValue>::SendType>
1973  void UpdateValues(
1974  const std::vector<TSendType>& rBuffer,
1975  MeshType& rSourceMesh,
1976  TDatabaseAccess& rAccess,
1977  TReductionOperation Operation)
1978  {
1979  auto& r_container = rAccess.GetContainer(rSourceMesh);
1980  const TSendType* p_buffer = rBuffer.data();
1981  std::size_t position = 0;
1982 
1983  for (auto iter = r_container.begin(); iter != r_container.end(); ++iter)
1984  {
1985  position += ReduceValues(p_buffer + position, rAccess, iter, Operation);
1986  }
1987 
1988  KRATOS_WARNING_IF_ALL_RANKS("MPICommunicator", position > rBuffer.size())
1989  << GetDataCommunicator()
1990  << "Error in estimating receive buffer size." << std::endl;
1991  }
1992 
1993  template<
1994  class TDatabaseAccess,
1995  typename TValue = typename TDatabaseAccess::ValueType>
1996  void UpdateValues(
1997  const std::string& rBuffer,
1998  MeshType& rSourceMesh,
1999  TDatabaseAccess& rAccess,
2000  Operation<OperationType::Replace>)
2001  {
2002  StreamSerializer serializer;
2003  std::stringstream* serializer_buffer = (std::stringstream *)serializer.pGetBuffer();
2004  serializer_buffer->write(rBuffer.data(), rBuffer.size());
2005 
2006  auto& r_container = rAccess.GetContainer(rSourceMesh);
2007  for (auto iter = r_container.begin(); iter != r_container.end(); ++iter)
2008  {
2009  serializer.load("Value", rAccess.GetValue(iter));
2010  }
2011  }
2012 
2013  template<
2014  typename TSourceAccess,
2015  typename TDestinationAccess,
2016  class TDatabaseAccess>
2017  void MatchDynamicVectorSizes(
2018  TSourceAccess SourceType,
2019  TDestinationAccess DestinationType,
2020  TDatabaseAccess& rAccess)
2021  {
2022  using TVectorType = typename TDatabaseAccess::ValueType;
2023  int destination = 0;
2024 
2025  NeighbourIndicesContainerType& neighbour_indices = NeighbourIndices();
2026 
2027  std::vector<int> send_sizes;
2028  std::vector<int> recv_sizes;
2029 
2030  bool resize_error = false;
2031  std::stringstream error_detail;
2032 
2033  for (unsigned int i_color = 0; i_color < neighbour_indices.size(); i_color++)
2034  {
2035  if ( (destination = neighbour_indices[i_color]) >= 0)
2036  {
2037  MeshType& r_source_mesh = GetMesh(i_color, SourceType);
2038  const auto& r_source_container = rAccess.GetContainer(r_source_mesh);
2039  const std::size_t num_values_to_send = r_source_container.size();
2040 
2041  MeshType& r_destination_mesh = GetMesh(i_color, DestinationType);
2042  auto& r_destination_container = rAccess.GetContainer(r_destination_mesh);
2043  const std::size_t num_values_to_recv = r_destination_container.size();
2044 
2045  if ( (num_values_to_send == 0) && (num_values_to_recv == 0) )
2046  {
2047  continue; // nothing to transfer, skip communication step
2048  }
2049 
2050  if (send_sizes.size() != num_values_to_send)
2051  {
2052  send_sizes.resize(num_values_to_send);
2053  }
2054 
2055  if (recv_sizes.size() != num_values_to_recv)
2056  {
2057  recv_sizes.resize(num_values_to_recv);
2058  }
2059 
2060  int position = 0;
2061  for (auto iter = r_source_container.begin(); iter != r_source_container.end(); ++iter)
2062  {
2063  const TVectorType& r_value = rAccess.GetValue(iter);
2064  send_sizes[position++] = r_value.size();
2065  }
2066 
2068  send_sizes, destination, i_color,
2069  recv_sizes, destination, i_color);
2070 
2071  position = 0;
2072  for (auto iter = r_destination_container.begin(); iter != r_destination_container.end(); ++iter)
2073  {
2074  std::size_t source_size = recv_sizes[position++];
2075  if (source_size != 0)
2076  {
2077  TVectorType& r_value = rAccess.GetValue(iter);
2078  if (r_value.size() == source_size)
2079  {
2080  continue; // everything ok!
2081  }
2082  else if (r_value.size() == 0)
2083  {
2084  r_value.resize(source_size, false);
2085  }
2086  else
2087  {
2088  resize_error = true;
2089  error_detail
2090  << "On rank " << mrDataCommunicator.Rank() << ": "
2091  << "local size: " << r_value.size() << " "
2092  << "source size: " << source_size << "." << std::endl;
2093  }
2094  }
2095  }
2096  }
2097  }
2098 
2100  << "Size mismatch in Vector size synchronization." << std::endl
2101  << error_detail.str();
2102  }
2103 
2104  template<
2105  typename TSourceAccess,
2106  typename TDestinationAccess,
2107  class TDatabaseAccess>
2108  void MatchDynamicMatrixSizes(
2109  TSourceAccess SourceType,
2110  TDestinationAccess DestinationType,
2111  TDatabaseAccess& rAccess)
2112  {
2113  using TMatrixType = typename TDatabaseAccess::ValueType;
2114  int destination = 0;
2115 
2116  NeighbourIndicesContainerType& neighbour_indices = NeighbourIndices();
2117 
2118  std::vector<int> send_sizes;
2119  std::vector<int> recv_sizes;
2120 
2121  bool resize_error = false;
2122  std::stringstream error_detail;
2123 
2124  for (unsigned int i_color = 0; i_color < neighbour_indices.size(); i_color++)
2125  {
2126  if ( (destination = neighbour_indices[i_color]) >= 0)
2127  {
2128  MeshType& r_source_mesh = GetMesh(i_color, SourceType);
2129  const auto& r_source_container = rAccess.GetContainer(r_source_mesh);
2130  const std::size_t num_values_to_send = 2*r_source_container.size();
2131 
2132  MeshType& r_destination_mesh = GetMesh(i_color, DestinationType);
2133  auto& r_destination_container = rAccess.GetContainer(r_destination_mesh);
2134  const std::size_t num_values_to_recv = 2*r_destination_container.size();
2135 
2136  if ( (num_values_to_send == 0) && (num_values_to_recv == 0) )
2137  {
2138  continue; // nothing to transfer, skip communication step
2139  }
2140 
2141  if (send_sizes.size() != num_values_to_send)
2142  {
2143  send_sizes.resize(num_values_to_send);
2144  }
2145 
2146  if (recv_sizes.size() != num_values_to_recv)
2147  {
2148  recv_sizes.resize(num_values_to_recv);
2149  }
2150 
2151  int position = 0;
2152  for (auto iter = r_source_container.begin(); iter != r_source_container.end(); ++iter)
2153  {
2154  const TMatrixType& r_value = rAccess.GetValue(iter);
2155  send_sizes[position++] = r_value.size1();
2156  send_sizes[position++] = r_value.size2();
2157  }
2158 
2160  send_sizes, destination, i_color,
2161  recv_sizes, destination, i_color);
2162 
2163  position = 0;
2164  for (auto iter = r_destination_container.begin(); iter != r_destination_container.end(); ++iter)
2165  {
2166  std::size_t source_size_1 = recv_sizes[position++];
2167  std::size_t source_size_2 = recv_sizes[position++];
2168  if (source_size_1 != 0 && source_size_2 != 0)
2169  {
2170  TMatrixType& r_value = rAccess.GetValue(iter);
2171  if (r_value.size1() == source_size_1 && r_value.size2() == source_size_2)
2172  {
2173  continue; // everything ok!
2174  }
2175  else if (r_value.size1() == 0 && r_value.size2() == 0)
2176  {
2177  r_value.resize(source_size_1, source_size_2, false);
2178  }
2179  else
2180  {
2181  resize_error = true;
2182  error_detail
2183  << "On rank " << mrDataCommunicator.Rank() << ": "
2184  << "local size: (" << r_value.size1() << "," << r_value.size2() << ") "
2185  << "source size: (" << source_size_1 << "," << source_size_2 << ")." << std::endl;
2186  }
2187  }
2188  }
2189  }
2190  }
2191 
2193  << "Size mismatch in Matrix size synchronization." << std::endl
2194  << error_detail.str();
2195  }
2196 
2200 
2201 
2205 
2206 
2210 
2211 
2213 
2214 }; // Class MPICommunicator
2215 
2217 
2220 
2221 
2225 
2226 
2228 inline std::istream & operator >>(std::istream& rIStream,
2229  MPICommunicator& rThis);
2230 
2232 
2233 inline std::ostream & operator <<(std::ostream& rOStream,
2234  const MPICommunicator& rThis)
2235 {
2236  rThis.PrintInfo(rOStream);
2237  rOStream << std::endl;
2238  rThis.PrintData(rOStream);
2239 
2240  return rOStream;
2241 }
2243 
2244 } // namespace Kratos.
2245 
2246 #endif // KRATOS_MPI_COMMUNICATOR_H_INCLUDED defined
The Commmunicator class manages communication for distributed ModelPart instances.
Definition: communicator.h:67
Communicator::Pointer Create() const
Definition: communicator.cpp:79
virtual void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: communicator.cpp:657
NeighbourIndicesContainerType & NeighbourIndices()
Definition: communicator.cpp:162
const DataCommunicator & mrDataCommunicator
Definition: communicator.h:513
MeshType & GhostMesh()
Returns the reference to the mesh storing all ghost entities.
Definition: communicator.cpp:251
virtual const DataCommunicator & GetDataCommunicator() const
Definition: communicator.cpp:340
MeshType & InterfaceMesh()
Returns the reference to the mesh storing all interface entities.
Definition: communicator.cpp:257
MeshType & LocalMesh()
Returns the reference to the mesh storing all local entities.
Definition: communicator.cpp:245
unsigned int IndexType
Definition: communicator.h:80
virtual void PrintData(std::ostream &rOStream, std::string const &rPrefixString="") const
Print object's data.
Definition: communicator.cpp:662
unsigned int SizeType
Definition: communicator.h:82
Base class for all Conditions.
Definition: condition.h:59
Serial (do-nothing) version of a wrapper class for MPI communication.
Definition: data_communicator.h:318
virtual bool ErrorIfTrueOnAnyRank(bool Condition) const
This function throws an error on ranks where Condition evaluates to false, if it evaluated to true on...
Definition: data_communicator.h:729
virtual void Barrier() const
Pause program execution until all threads reach this call.
Definition: data_communicator.h:386
virtual int Size() const
Get the parallel size of this DataCommunicator.
Definition: data_communicator.h:597
TObject SendRecv(const TObject &rSendObject, const int SendDestination, const int SendTag, const int RecvSource, const int RecvTag) const
Exchange data with other ranks.
Definition: data_communicator.h:492
virtual int Rank() const
Get the parallel rank for this DataCommunicator.
Definition: data_communicator.h:587
virtual bool IsDistributed() const
Check whether this DataCommunicator is aware of parallelism.
Definition: data_communicator.h:606
Base class for all Elements.
Definition: element.h:60
Definition: flags.h:58
static const Flags AllDefined()
Definition: flags.h:252
MPICommunicator manages the transfer of ModelPart data in MPI distributed memory environment.
Definition: mpi_communicator.h:569
bool AssembleNonHistoricalData(Variable< DenseVector< array_1d< double, 3 > > > const &ThisVariable) override
Definition: mpi_communicator.h:1118
bool SynchronizeNodalFlags() override
Definition: mpi_communicator.h:1294
Communicator::Pointer Create(const DataCommunicator &rDataCommunicator) const override
Definition: mpi_communicator.h:730
bool SynchronizeVariable(Variable< array_1d< double, 6 > > const &rThisVariable) override
Definition: mpi_communicator.h:821
MPICommunicator & operator=(MPICommunicator const &rOther)=delete
Assignment operator.
bool SynchronizeNonHistoricalVariable(Variable< array_1d< double, 3 > > const &rThisVariable) override
Definition: mpi_communicator.h:877
bool SynchronizeVariable(Variable< array_1d< double, 3 > > const &rThisVariable) override
Definition: mpi_communicator.h:807
bool TransferObjects(std::vector< NodesContainerType > &SendObjects, std::vector< NodesContainerType > &RecvObjects) override
Definition: mpi_communicator.h:1197
BaseType::SizeType SizeType
Definition: mpi_communicator.h:616
bool SynchronizeNonHistoricalVariable(Variable< int > const &rThisVariable) override
Definition: mpi_communicator.h:856
bool SynchronizeNonHistoricalDataToMin(Variable< double > const &ThisVariable) override
Synchronize variable in nodal data to the minimum value across all processes.
Definition: mpi_communicator.h:1011
bool SynchronizeVariable(Variable< int > const &rThisVariable) override
Definition: mpi_communicator.h:786
bool SynchronizeElementalNonHistoricalVariable(Variable< Matrix > const &ThisVariable) override
Definition: mpi_communicator.h:1183
BaseType::ElementType ElementType
Definition: mpi_communicator.h:622
BaseType::PropertiesType PropertiesType
Definition: mpi_communicator.h:620
MeshType::NodesContainerType NodesContainerType
Nodes container. Which is a vector set of nodes with their Id's as key.
Definition: mpi_communicator.h:633
bool SynchronizeNonHistoricalDataToAbsMax(Variable< double > const &ThisVariable) override
Synchronize variable in nodal data to the absolute maximum value across all processes.
Definition: mpi_communicator.h:977
~MPICommunicator() override=default
Destructor.
bool TransferObjects(std::vector< NodesContainerType > &SendObjects, std::vector< NodesContainerType > &RecvObjects, Kratos::Serializer &particleSerializer) override
Definition: mpi_communicator.h:1230
bool AssembleCurrentData(Variable< array_1d< double, 3 > > const &ThisVariable) override
Definition: mpi_communicator.h:1076
std::string Info() const override
Turn back information as a string.
Definition: mpi_communicator.h:1334
bool SynchronizeVariable(Variable< array_1d< double, 4 > > const &rThisVariable) override
Definition: mpi_communicator.h:814
bool SynchronizeElementalNonHistoricalVariable(Variable< DenseVector< array_1d< double, 3 > > > const &ThisVariable) override
Definition: mpi_communicator.h:1162
KRATOS_DEPRECATED_MESSAGE("This constructor is deprecated, please use the one that accepts a DataCommunicator") MPICommunicator(VariablesList *Variables_list)
Constructor using the VariablesList of the ModelPart that will use this communicator.
Definition: mpi_communicator.h:707
bool SynchronizeElementalNonHistoricalVariable(Variable< int > const &ThisVariable) override
Definition: mpi_communicator.h:1141
bool TransferObjects(std::vector< ConditionsContainerType > &SendObjects, std::vector< ConditionsContainerType > &RecvObjects) override
Definition: mpi_communicator.h:1219
bool SynchronizeCurrentDataToAbsMax(Variable< double > const &ThisVariable) override
Synchronize variable in nodal solution step data to the absolute maximum value across all processes.
Definition: mpi_communicator.h:960
bool SynchronizeNonHistoricalDataToAbsMin(Variable< double > const &ThisVariable) override
Synchronize variable in nodal data to the absolute minimum value across all processes.
Definition: mpi_communicator.h:1045
bool TransferObjects(std::vector< ConditionsContainerType > &SendObjects, std::vector< ConditionsContainerType > &RecvObjects, Kratos::Serializer &particleSerializer) override
Definition: mpi_communicator.h:1252
bool SynchronizeVariable(Variable< bool > const &rThisVariable) override
Definition: mpi_communicator.h:800
bool SynchronizeDofs() override
Definition: mpi_communicator.h:774
bool IsDistributed() const override
Definition: mpi_communicator.h:753
bool AssembleCurrentData(Variable< Matrix > const &ThisVariable) override
Definition: mpi_communicator.h:1090
bool SynchronizeCurrentDataToMax(Variable< double > const &ThisVariable) override
Synchronize variable in nodal solution step data to the maximum value across all processes.
Definition: mpi_communicator.h:926
Communicator BaseType
Definition: mpi_communicator.h:612
bool SynchronizeVariable(Variable< Matrix > const &rThisVariable) override
Definition: mpi_communicator.h:842
MPICommunicator(MPICommunicator const &rOther)
Copy constructor.
Definition: mpi_communicator.h:723
MeshType::ElementConstantIterator ElementConstantIterator
Definition: mpi_communicator.h:685
bool SynchronizeNonHistoricalDataToMax(Variable< double > const &ThisVariable) override
Synchronize variable in nodal data to the maximum value across all processes.
Definition: mpi_communicator.h:943
bool AssembleNonHistoricalData(Variable< Matrix > const &ThisVariable) override
Definition: mpi_communicator.h:1132
bool SynchronizeNonHistoricalVariable(Variable< bool > const &rThisVariable) override
Definition: mpi_communicator.h:870
MeshType::ConditionIterator ConditionIterator
Definition: mpi_communicator.h:694
bool SynchronizeElementalNonHistoricalVariable(Variable< array_1d< double, 3 > > const &ThisVariable) override
Definition: mpi_communicator.h:1155
bool SynchronizeElementalFlags() override
Definition: mpi_communicator.h:1305
BaseType::NodeType NodeType
Definition: mpi_communicator.h:618
bool SynchronizeNonHistoricalVariable(Variable< double > const &rThisVariable) override
Definition: mpi_communicator.h:863
MeshType::ConditionsContainerType ConditionsContainerType
Condintions container. A vector set of Conditions with their Id's as key.
Definition: mpi_communicator.h:688
bool AssembleCurrentData(Variable< Vector > const &ThisVariable) override
Definition: mpi_communicator.h:1083
bool SynchronizeCurrentDataToAbsMin(Variable< double > const &ThisVariable) override
Synchronize variable in nodal solution step data to the absolute minimum value across all processes.
Definition: mpi_communicator.h:1028
MPICommunicator(VariablesList *pVariablesList, const DataCommunicator &rDataCommunicator)
Constructor using the VariablesList and a custom DataCommunicator.
Definition: mpi_communicator.h:714
MeshType::PropertiesContainerType PropertiesContainerType
Properties container. Which is a vector set of Properties with their Id's as key.
Definition: mpi_communicator.h:653
BaseType::ConditionType ConditionType
Definition: mpi_communicator.h:624
bool AssembleNonHistoricalData(Variable< int > const &ThisVariable) override
Definition: mpi_communicator.h:1097
bool AssembleNonHistoricalData(Variable< Vector > const &ThisVariable) override
Definition: mpi_communicator.h:1125
bool AssembleCurrentData(Variable< double > const &ThisVariable) override
Definition: mpi_communicator.h:1069
bool SynchronizeNonHistoricalVariable(Variable< array_1d< double, 4 > > const &rThisVariable) override
Definition: mpi_communicator.h:884
bool SynchronizeVariable(Variable< Quaternion< double >> const &rThisVariable) override
Definition: mpi_communicator.h:849
MeshType::NodeIterator NodeIterator
Definition: mpi_communicator.h:639
bool AssembleCurrentData(Variable< int > const &ThisVariable) override
Definition: mpi_communicator.h:1062
bool SynchronizeVariable(Variable< Vector > const &rThisVariable) override
Definition: mpi_communicator.h:835
bool SynchronizeNonHistoricalVariable(Variable< array_1d< double, 6 > > const &rThisVariable) override
Definition: mpi_communicator.h:891
bool SynchronizeCurrentDataToMin(Variable< double > const &ThisVariable) override
Synchronize variable in nodal solution step data to the minimum value across all processes.
Definition: mpi_communicator.h:994
BaseType::IndexType IndexType
Definition: mpi_communicator.h:614
bool SynchronizeElementalNonHistoricalVariable(Variable< double > const &ThisVariable) override
Definition: mpi_communicator.h:1148
MeshType::PropertiesIterator PropertiesIterator
Definition: mpi_communicator.h:659
MeshType::NodeConstantIterator NodeConstantIterator
Definition: mpi_communicator.h:645
BaseType::MeshesContainerType MeshesContainerType
Definition: mpi_communicator.h:630
BaseType::NeighbourIndicesContainerType NeighbourIndicesContainerType
Definition: mpi_communicator.h:626
bool SynchronizeNonHistoricalVariable(Variable< Quaternion< double >> const &rThisVariable) override
Definition: mpi_communicator.h:919
bool SynchronizeAndNodalFlags(const Flags &TheFlags) override
Definition: mpi_communicator.h:1280
MeshType::ElementIterator ElementIterator
Definition: mpi_communicator.h:679
bool AssembleNonHistoricalData(Variable< double > const &ThisVariable) override
Definition: mpi_communicator.h:1104
bool TransferObjects(std::vector< ElementsContainerType > &SendObjects, std::vector< ElementsContainerType > &RecvObjects, Kratos::Serializer &particleSerializer) override
Definition: mpi_communicator.h:1241
bool SynchronizeNonHistoricalVariable(Variable< Matrix > const &rThisVariable) override
Definition: mpi_communicator.h:912
KRATOS_CLASS_POINTER_DEFINITION(MPICommunicator)
Pointer definition of MPICommunicator.
bool SynchronizeNonHistoricalVariable(Variable< array_1d< double, 9 > > const &rThisVariable) override
Definition: mpi_communicator.h:898
bool SynchronizeOrNodalFlags(const Flags &TheFlags) override
Definition: mpi_communicator.h:1262
bool SynchronizeElementalNonHistoricalVariable(Variable< DenseVector< int > > const &ThisVariable) override
Definition: mpi_communicator.h:1169
bool SynchronizeVariable(Variable< double > const &rThisVariable) override
Definition: mpi_communicator.h:793
MeshType::ElementsContainerType ElementsContainerType
Element container. A vector set of Elements with their Id's as key.
Definition: mpi_communicator.h:673
bool SynchronizeElementalNonHistoricalVariable(Variable< Vector > const &ThisVariable) override
Definition: mpi_communicator.h:1176
MeshType::PropertiesConstantIterator PropertiesConstantIterator
Definition: mpi_communicator.h:665
BaseType::MeshType MeshType
Definition: mpi_communicator.h:628
bool TransferObjects(std::vector< ElementsContainerType > &SendObjects, std::vector< ElementsContainerType > &RecvObjects) override
Definition: mpi_communicator.h:1208
bool AssembleNonHistoricalData(Variable< array_1d< double, 3 > > const &ThisVariable) override
Definition: mpi_communicator.h:1111
bool SynchronizeNodalSolutionStepsData() override
Definition: mpi_communicator.h:762
bool SynchronizeVariable(Variable< array_1d< double, 9 > > const &rThisVariable) override
Definition: mpi_communicator.h:828
bool SynchronizeNonHistoricalVariable(Variable< Vector > const &rThisVariable) override
Definition: mpi_communicator.h:905
MeshType::ConditionConstantIterator ConditionConstantIterator
Definition: mpi_communicator.h:700
static MPI_Comm GetMPICommunicator(const DataCommunicator &rDataCommunicator)
Get the underlying MPI_Comm instance.
Definition: mpi_data_communicator.cpp:431
Definition: mpi_communicator.h:498
Node::DofsContainerType ValueType
Definition: mpi_communicator.h:501
typename SendTraits< ValueType >::SendType SendType
Definition: mpi_communicator.h:502
const ValueType & GetValue(const ConstIteratorType &iter)
Definition: mpi_communicator.h:509
ValueType & GetValue(IteratorType &iter)
Definition: mpi_communicator.h:504
Definition: mpi_communicator.h:386
const ContainerType & GetContainer(const Communicator::MeshType &rMesh)
Definition: mpi_communicator.h:398
ContainerType & GetContainer(Communicator::MeshType &rMesh)
Definition: mpi_communicator.h:393
Communicator::MeshType::ElementsContainerType::iterator IteratorType
Definition: mpi_communicator.h:390
Communicator::MeshType::ElementsContainerType::const_iterator ConstIteratorType
Definition: mpi_communicator.h:391
Definition: mpi_communicator.h:516
ElementalDataAccess(const Variable< TValue > &mrVariable)
Definition: mpi_communicator.h:524
typename SendTraits< TValue >::SendType SendType
Definition: mpi_communicator.h:522
const TValue & GetValue(const ConstIteratorType &iter)
Definition: mpi_communicator.h:534
TValue & GetValue(IteratorType &iter)
Definition: mpi_communicator.h:529
TValue ValueType
Definition: mpi_communicator.h:521
Definition: mpi_communicator.h:541
ElementalFlagsAccess(const Kratos::Flags &rMask)
Definition: mpi_communicator.h:549
Kratos::Flags & GetValue(IteratorType &iter)
Definition: mpi_communicator.h:554
typename SendTraits< ValueType >::SendType SendType
Definition: mpi_communicator.h:547
const Kratos::Flags & GetValue(const ConstIteratorType &iter)
Definition: mpi_communicator.h:559
const Kratos::Flags & mrMask
Definition: mpi_communicator.h:544
Definition: mpi_communicator.h:368
Communicator::MeshType::NodesContainerType::const_iterator ConstIteratorType
Definition: mpi_communicator.h:373
ContainerType & GetContainer(Communicator::MeshType &rMesh)
Definition: mpi_communicator.h:375
Communicator::MeshType::NodesContainerType::iterator IteratorType
Definition: mpi_communicator.h:372
const ContainerType & GetContainer(const Communicator::MeshType &rMesh)
Definition: mpi_communicator.h:380
Definition: mpi_communicator.h:430
NodalDataAccess(const Variable< TValue > &mrVariable)
Definition: mpi_communicator.h:438
const TValue & GetValue(const ConstIteratorType &iter)
Definition: mpi_communicator.h:448
TValue ValueType
Definition: mpi_communicator.h:435
typename SendTraits< TValue >::SendType SendType
Definition: mpi_communicator.h:436
TValue & GetValue(IteratorType &iter)
Definition: mpi_communicator.h:443
Definition: mpi_communicator.h:455
const Kratos::Flags & mrMask
Definition: mpi_communicator.h:458
Kratos::Flags & GetValue(IteratorType &iter)
Definition: mpi_communicator.h:468
NodalFlagsAccess(const Kratos::Flags &rMask)
Definition: mpi_communicator.h:463
const Kratos::Flags & GetValue(const ConstIteratorType &iter)
Definition: mpi_communicator.h:473
typename SendTraits< ValueType >::SendType SendType
Definition: mpi_communicator.h:461
Definition: mpi_communicator.h:480
typename SendTraits< ValueType >::SendType SendType
Definition: mpi_communicator.h:484
ValueType & GetValue(IteratorType &iter)
Definition: mpi_communicator.h:486
const ValueType & GetValue(const ConstIteratorType &iter)
Definition: mpi_communicator.h:491
Definition: mpi_communicator.h:405
typename SendTraits< TValue >::SendType SendType
Definition: mpi_communicator.h:411
TValue ValueType
Definition: mpi_communicator.h:410
const TValue & GetValue(const ConstIteratorType &iter)
Definition: mpi_communicator.h:423
NodalSolutionStepValueAccess(const Variable< TValue > &mrVariable)
Definition: mpi_communicator.h:413
TValue & GetValue(IteratorType &iter)
Definition: mpi_communicator.h:418
NodesContainerType & Nodes()
Definition: mesh.h:346
typename NodesContainerType::const_iterator NodeConstantIterator
Const iterator for nodes in the container. Provides direct references to nodes.
Definition: mesh.h:117
typename PropertiesContainerType::iterator PropertiesIterator
Iterator for properties in the container. Provides direct references to properties.
Definition: mesh.h:123
typename ConditionsContainerType::iterator ConditionIterator
Iterator for conditions in the container. Provides direct references to conditions.
Definition: mesh.h:153
PointerVectorSet< ElementType, IndexedObject, std::less< typename IndexedObject::result_type >, std::equal_to< typename IndexedObject::result_type >, typename ElementType::Pointer, std::vector< typename ElementType::Pointer > > ElementsContainerType
Type alias for the container of elements.
Definition: mesh.h:135
typename NodesContainerType::iterator NodeIterator
Iterator for nodes in the container. Provides direct references to nodes.
Definition: mesh.h:114
PointerVectorSet< NodeType, IndexedObject, std::less< typename IndexedObject::result_type >, std::equal_to< typename IndexedObject::result_type >, typename NodeType::Pointer, std::vector< typename NodeType::Pointer > > NodesContainerType
Type alias for the container of nodes.
Definition: mesh.h:111
typename ConditionsContainerType::const_iterator ConditionConstantIterator
Const iterator for conditions in the container. Provides direct references to conditions.
Definition: mesh.h:156
typename ElementsContainerType::const_iterator ElementConstantIterator
Const iterator for elements in the container. Provides direct references to elements.
Definition: mesh.h:141
typename ElementsContainerType::iterator ElementIterator
Iterator for elements in the container. Provides direct references to elements.
Definition: mesh.h:138
typename PropertiesContainerType::const_iterator PropertiesConstantIterator
Const iterator for properties in the container. Provides direct references to properties.
Definition: mesh.h:126
ElementsContainerType & Elements()
Definition: mesh.h:568
Definition: mpi_serializer.h:33
This class defines the node.
Definition: node.h:65
std::vector< std::unique_ptr< Dof< double > >> DofsContainerType
The DoF container type definition.
Definition: node.h:92
A sorted associative container similar to an STL set, but uses a vector to store pointers to its data...
Definition: pointer_vector_set.h:72
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: pointer_vector_set.h:95
boost::indirect_iterator< typename TContainerType::const_iterator > const_iterator
Definition: pointer_vector_set.h:96
Properties encapsulates data shared by different Elements or Conditions. It can store any type of dat...
Definition: properties.h:69
Quaternion A simple class that implements the main features of quaternion algebra.
Definition: quaternion.h:28
void SetX(const T &value)
Definition: quaternion.h:122
void SetZ(const T &value)
Definition: quaternion.h:138
void SetW(const T &value)
Definition: quaternion.h:146
const T W() const
Definition: quaternion.h:145
void SetY(const T &value)
Definition: quaternion.h:130
const T Y() const
Definition: quaternion.h:129
const T X() const
Definition: quaternion.h:121
const T Z() const
Definition: quaternion.h:137
The serialization consists in storing the state of an object into a storage format like data file or ...
Definition: serializer.h:123
void load(std::string const &rTag, TDataType &rObject)
Definition: serializer.h:207
void save(std::string const &rTag, std::array< TDataType, TDataSize > const &rObject)
Definition: serializer.h:545
BufferType * pGetBuffer()
Definition: serializer.h:903
A shared variable list gives the position of each variable in the containers sharing it.
Definition: variables_list_data_value_container.h:61
SizeType TotalSize() const
Definition: variables_list_data_value_container.h:392
BlockType * Data()
Definition: variables_list_data_value_container.h:592
Holds a list of variables and their position in VariablesListDataValueContainer.
Definition: variables_list.h:50
Short class definition.
Definition: array_1d.h:61
#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
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
#define KRATOS_WARNING_IF_ALL_RANKS(label, conditional)
Definition: logger.h:276
TContainerType & GetContainer(ModelPart::MeshType &rMesh)
static double max(double a, double b)
Definition: GeometryFunctions.h:79
static double min(double a, double b)
Definition: GeometryFunctions.h:71
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
ModelPart::NodesContainerType NodesContainerType
Definition: find_conditions_neighbours_process.h:44
REACTION_CHECK_STIFFNESS_FACTOR INNER_LOOP_ITERATION DISTANCE_THRESHOLD ACTIVE_CHECK_FACTOR AUXILIAR_COORDINATES NORMAL_GAP WEIGHTED_GAP WEIGHTED_SCALAR_RESIDUAL bool
Definition: contact_structural_mechanics_application_variables.h:93
@ Local
Definition: traits.h:20
@ Ghost
Definition: traits.h:21
TExpressionType::data_type sum(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:675
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
REACTION_CHECK_STIFFNESS_FACTOR int
Definition: contact_structural_mechanics_application_variables.h:75
TABLE_NUMBER_ANGULAR_VELOCITY TABLE_NUMBER_MOMENT I33 BEAM_INERTIA_ROT_UNIT_LENGHT_Y KRATOS_DEFINE_APPLICATION_VARIABLE(DEM_APPLICATION, double, BEAM_INERTIA_ROT_UNIT_LENGHT_Z) typedef std double
Definition: DEM_application_variables.h:182
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
color
Definition: all_t_win_vs_m_fixed_error.py:230
int j
Definition: quadrature.py:648
string tag
Definition: regular_mesher.py:14
integer i
Definition: TensorModule.f:17
static std::size_t GetSendSize(const ValueType &rValue)
Definition: mpi_communicator.h:362
static std::size_t GetSendSize(TDatabaseAccess &rAccess, const Communicator::MeshType &rSourceMesh)
Definition: mpi_communicator.h:350
typename TDatabaseAccess::ValueType ValueType
Definition: mpi_communicator.h:349
static std::size_t GetSendSize(TDatabaseAccess &rAccess, const Communicator::MeshType &rSourceMesh)
Definition: mpi_communicator.h:334
typename TDatabaseAccess::ValueType ValueType
Definition: mpi_communicator.h:333
static std::size_t GetSendSize(const ValueType &)
Definition: mpi_communicator.h:341
Definition: mpi_communicator.h:325
static std::size_t GetSendSize(const ValueType &rValue)
static std::size_t GetSendSize(TDatabaseAccess &rAccess, const Communicator::MeshType &rSourceMesh)
typename TDatabaseAccess::ValueType ValueType
Definition: mpi_communicator.h:326
Definition: mpi_communicator.h:184
static void WriteBuffer(const ValueType &rValue, SendType *pBuffer)
Definition: mpi_communicator.h:187
static void ReadBuffer(const SendType *pBuffer, ValueType &rValue)
Definition: mpi_communicator.h:192
typename SendTraits< ValueType >::SendType SendType
Definition: mpi_communicator.h:185
Definition: mpi_communicator.h:199
static void ReadBuffer(const SendType *pBuffer, ValueType &rValue)
Definition: mpi_communicator.h:207
static void WriteBuffer(const ValueType &rValue, SendType *pBuffer)
Definition: mpi_communicator.h:202
typename SendTraits< ValueType >::SendType SendType
Definition: mpi_communicator.h:200
typename SendTraits< DenseVector< TVectorValue > >::SendType SendType
Definition: mpi_communicator.h:264
static void ReadBuffer(const SendType *pBuffer, DenseVector< TVectorValue > &rValue)
Definition: mpi_communicator.h:271
static void WriteBuffer(const DenseVector< TVectorValue > &rValue, SendType *pBuffer)
Definition: mpi_communicator.h:266
typename SendTraits< Kratos::VariablesListDataValueContainer >::SendType SendType
Definition: mpi_communicator.h:284
static void ReadBuffer(const SendType *pBuffer, Kratos::VariablesListDataValueContainer &rValue)
Definition: mpi_communicator.h:291
static void WriteBuffer(const Kratos::VariablesListDataValueContainer &rValue, SendType *pBuffer)
Definition: mpi_communicator.h:286
static void ReadBuffer(const SendType *pBuffer, Node::DofsContainerType &rValue)
Definition: mpi_communicator.h:311
SendTraits< Node::DofsContainerType >::SendType SendType
Definition: mpi_communicator.h:299
static void WriteBuffer(const Node::DofsContainerType &rValue, SendType *pBuffer)
Definition: mpi_communicator.h:301
static void WriteBuffer(const Quaternion< double > &rValue, SendType *pBuffer)
Definition: mpi_communicator.h:244
static void ReadBuffer(const SendType *pBuffer, Quaternion< double > &rValue)
Definition: mpi_communicator.h:252
SendTraits< Quaternion< double > >::SendType SendType
Definition: mpi_communicator.h:242
Definition: mpi_communicator.h:213
std::vector< SendType > BufferType
Definition: mpi_communicator.h:149
static std::size_t GetMessageSize(const DenseVector< TVectorValue > &rValue)
Definition: mpi_communicator.h:152
double SendType
Definition: mpi_communicator.h:148
double SendType
Definition: mpi_communicator.h:108
std::vector< SendType > BufferType
Definition: mpi_communicator.h:109
static std::size_t GetMessageSize(const Kratos::VariablesListDataValueContainer &rValue)
Definition: mpi_communicator.h:165
double SendType
Definition: mpi_communicator.h:128
static std::size_t GetMessageSize(const Matrix &rValue)
Definition: mpi_communicator.h:132
std::vector< SendType > BufferType
Definition: mpi_communicator.h:129
std::vector< SendType > BufferType
Definition: mpi_communicator.h:174
static std::size_t GetMessageSize(const Node::DofsContainerType &rValue)
Definition: mpi_communicator.h:177
int SendType
Definition: mpi_communicator.h:173
std::vector< SendType > BufferType
Definition: mpi_communicator.h:141
double SendType
Definition: mpi_communicator.h:140
double SendType
Definition: mpi_communicator.h:116
std::vector< SendType > BufferType
Definition: mpi_communicator.h:117
static std::size_t GetMessageSize(const Vector &rValue)
Definition: mpi_communicator.h:120
double SendType
Definition: mpi_communicator.h:100
std::vector< SendType > BufferType
Definition: mpi_communicator.h:101
std::vector< SendType > BufferType
Definition: mpi_communicator.h:85
int SendType
Definition: mpi_communicator.h:84
std::vector< SendType > BufferType
Definition: mpi_communicator.h:93
double SendType
Definition: mpi_communicator.h:92
int SendType
Definition: mpi_communicator.h:76
std::vector< SendType > BufferType
Definition: mpi_communicator.h:77
Definition: mpi_communicator.h:72
Configure::IteratorType IteratorType
Definition: transfer_utility.h:249