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.
debug_utilities.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main author: Carlos A. Roig
11 // Riccardo Rossi
12 //
13 
14 #pragma once
15 
16 // System includes
17 #include <vector>
18 #include <sstream>
19 
20 // External includes
21 
22 // Project includes
23 #include "includes/model_part.h"
29 
30 #define KRATOS_SINGLE_VARIABLE_TYPES bool, int, double, unsigned int
31 #define KRATOS_BOUNDED_VECTOR_VARIABLE_TYPES array_1d<double,3>, array_1d<double,4>, array_1d<double,6>, array_1d<double,9>
32 #define KRATOS_UNBOUNDED_VECTOR_VARIABLE_TYPES Vector, Matrix
33 
34 namespace Kratos {
35 
37 public:
38 
40 
42 
43  template <class T, class... Ts>
44  struct is_any : std::integral_constant<bool, (std::is_same<T, Ts>::value || ...)> {};
45 
46  template<class TVarType> struct is_kratos_single_variable : is_any<TVarType, KRATOS_SINGLE_VARIABLE_TYPES> {};
47  template<class TVarType> struct is_kratos_bounded_vector_variable : is_any<TVarType, KRATOS_BOUNDED_VECTOR_VARIABLE_TYPES> {};
48  template<class TVarType> struct is_kratos_unbounded_vector_variable : is_any<TVarType, KRATOS_UNBOUNDED_VECTOR_VARIABLE_TYPES> {};
49 
50  template<class TVarType, class TReturnType> using EnalbeIfSingle = typename std::enable_if<is_kratos_single_variable<TVarType>::value, TReturnType>::type;
51  template<class TVarType, class TReturnType> using EnalbeIfBoundedVector = typename std::enable_if<is_kratos_bounded_vector_variable<TVarType>::value, TReturnType>::type;
52  template<class TVarType, class TReturnType> using EnalbeIfUnbounedVector = typename std::enable_if<is_kratos_unbounded_vector_variable<TVarType>::value, TReturnType>::type;
53 
54  // Entrypoint to check all variables. Not yet tested
55  // static void CheckNodalHistoricalDatabase(ModelPart & rModelPart) {
56  // // Build the list of indices and the pointer communicator
57  // DataCommunicator& r_default_comm = ParallelEnvironment::GetDefaultDataCommunicator();
58  // std::vector<int> indices;
59 
60  // auto node_list = rModelPart.Nodes();
61 
62  // for(auto& node : node_list) {
63  // indices.push_back(node.Id());
64  // }
65 
66  // auto gp_map = GlobalPointerUtilities::RetrieveGlobalIndexedPointersMap(node_list, indices, r_default_comm );
67  // auto gp_list = GlobalPointerUtilities::RetrieveGlobalIndexedPointers(node_list, indices, r_default_comm );
68 
69  // GlobalPointerCommunicator<Node> pointer_comm(r_default_comm, gp_list.ptr_begin(), gp_list.ptr_end());
70 
71  // // Note: I think this can be change for an access function with std::tuple of the variables instead of a loop, but not in C++11/14
72  // for(auto & variableData: rModelPart.GetNodalSolutionStepVariablesList()) {
73  // auto & variable = KratosComponents<VariableComponentType>::Get(variableData.Name());
74  // CheckNodalHistoricalVariable(rModelPart, variable, pointer_comm, gp_map);
75  // }
76  // }
77 
78  // Trait Specialization
79  template<class TVarType>
80  static EnalbeIfSingle<TVarType, bool> InteralCmpEq(const TVarType& rVar1, const TVarType& rVar2)
81  {
82  return rVar1 == rVar2;
83  }
84 
85  template<class TVarType>
86  static EnalbeIfBoundedVector<TVarType, bool> InteralCmpEq(const TVarType& rVar1, const TVarType& rVar2)
87  {
88  for(typename TVarType::array_type::size_type i = 0; i < std::tuple_size<typename TVarType::array_type>::value; i++) {
89  if(rVar1[i] != rVar2[i]) return false;
90  }
91  return true;
92  }
93 
94  template<class TVarType, class TContainerType>
96  ModelPart & rModelPart,
97  const TContainerType & rContainer,
98  const TVarType & rVariable)
99  {
100  // Build the list of indices and the pointer communicator
102  std::vector<int> indices;
103 
104  for(auto& entity : rContainer) {
105  indices.push_back(entity.Id());
106  }
107 
108  auto gp_map = GlobalPointerUtilities::RetrieveGlobalIndexedPointersMap(rContainer, indices, r_default_comm );
109  auto gp_list = GlobalPointerUtilities::RetrieveGlobalIndexedPointers(rContainer, indices, r_default_comm );
110 
111  GlobalPointerCommunicator<typename TContainerType::data_type> pointer_comm(r_default_comm, gp_list.ptr_begin(), gp_list.ptr_end());
112 
113  CheckNonHistoricalVariable(rModelPart, rContainer, rVariable, pointer_comm, gp_map);
114  }
115 
116  template<class TContainerType, class TVarType>
118  ModelPart & rModelPart,
119  const TContainerType & rContainer,
120  const TVarType & rVariable,
122  std::unordered_map<int, GlobalPointer<typename TContainerType::data_type>> & gp_map)
123  {
125 
126  bool val_error_detected = false;
127 
128  std::stringstream error_stream;
129 
130  // Create the data functior
131  auto data_proxy = rPointerCommunicator.Apply(
132  [&rVariable](GlobalPointer<typename TContainerType::data_type>& gp)-> typename TVarType::Type {
133  return gp->GetValue(rVariable);
134  }
135  );
136 
137  // Check variable for all entities.
138  for(auto& entity : rContainer) {
139  auto& gp = gp_map[entity.Id()];
140 
141  if(!InteralCmpEq(entity.GetValue(rVariable),data_proxy.Get(gp))) {
142  std::cout << r_default_comm.Rank() << " Inconsistent variable value for Id: " << entity.Id() << " Expected: " << entity.GetValue(rVariable) << " Obtained " << data_proxy.Get(gp) << std::endl;
143  val_error_detected = true;
144  }
145  }
146 
147  if(val_error_detected) {
148  error_stream << "Value error(s) found" << std::endl;
149  }
150 
151  if(error_stream.rdbuf()->in_avail())
152  {
153  KRATOS_ERROR << error_stream.str() << std::endl;
154  }
155  }
156 
157  // Historical Variables
158 
159  template<class TVarType>
161  ModelPart & rModelPart,
162  const TVarType & rVariable)
163  {
164  // Build the list of indices and the pointer communicator
166  std::vector<int> indices;
167 
168  auto node_list = rModelPart.Nodes();
169 
170  for(auto& node : node_list) {
171  indices.push_back(node.Id());
172  }
173 
174  auto gp_map = GlobalPointerUtilities::RetrieveGlobalIndexedPointersMap(node_list, indices, r_default_comm );
175  auto gp_list = GlobalPointerUtilities::RetrieveGlobalIndexedPointers(node_list, indices, r_default_comm );
176 
177  GlobalPointerCommunicator<Node> pointer_comm(r_default_comm, gp_list.ptr_begin(), gp_list.ptr_end());
178 
179  CheckHistoricalVariable(rModelPart, rVariable, pointer_comm, gp_map);
180  }
181 
182  template<class TVarType>
184  ModelPart & rModelPart,
185  const TVarType & rVariable,
186  GlobalPointerCommunicator<Node> & rPointerCommunicator,
187  std::unordered_map<int, GlobalPointer<Node>> & gp_map)
188  {
190 
191  bool val_error_detected = false;
192  bool fix_error_detected = false;
193 
194  std::stringstream error_stream;
195 
196  // Create the data functior
197  auto data_proxy = rPointerCommunicator.Apply(
198  [&rVariable](GlobalPointer< Node >& gp)-> std::pair<typename TVarType::Type, bool> {
199  return {gp->FastGetSolutionStepValue(rVariable),gp->IsFixed(rVariable)};
200  }
201  );
202 
203  // Check variable for all nodes.
204  for(auto& node : rModelPart.Nodes()) {
205  auto& gp = gp_map[node.Id()];
206 
207  // Check Variable
208  if(!InteralCmpEq(node.FastGetSolutionStepValue(rVariable),data_proxy.Get(gp).first)) {
209  std::cout << r_default_comm.Rank() << " Inconsistent variable value for Id: " << node.Id() << " Expected: " << node.FastGetSolutionStepValue(rVariable) << " Obtained " << data_proxy.Get(gp).first << std::endl;
210  val_error_detected = true;
211  }
212  }
213 
214  // Check fixity for all nodes.
215  for(auto& node : rModelPart.Nodes()) {
216  auto& gp = gp_map[node.Id()];
217 
218  // Check Fixity
219  if(node.IsFixed(rVariable) != data_proxy.Get(gp).second) {
220  std::cout << r_default_comm.Rank() << " Inconsistent variable Fix for Id: " << node.Id() << " Expected: " << node.IsFixed(rVariable) << " Obtained " << data_proxy.Get(gp).second << std::endl;
221  fix_error_detected = true;
222  }
223  }
224 
225  if(val_error_detected) {
226  error_stream << "Value error(s) found" << std::endl;
227  }
228 
229  if(fix_error_detected) {
230  error_stream << "Fixity error(s) found" << std::endl;
231  }
232 
233  if(error_stream.rdbuf()->in_avail())
234  {
235  KRATOS_ERROR << error_stream.str() << std::endl;
236  }
237  }
238 };
239 
240 } // namespace Kratos
Serial (do-nothing) version of a wrapper class for MPI communication.
Definition: data_communicator.h:318
virtual int Rank() const
Get the parallel rank for this DataCommunicator.
Definition: data_communicator.h:587
A template class for handling communication related to global pointers.
Definition: pointer_communicator.h:178
ResultsProxy< TPointerDataType, TFunctorType > Apply(TFunctorType &&UserFunctor)
Applies a user-provided function to the global pointers and return a proxy to the results.
Definition: pointer_communicator.h:266
This class is a wrapper for a pointer to a data that is located in a different rank.
Definition: global_pointer.h:44
static std::unordered_map< int, GlobalPointer< typename TContainerType::value_type > > RetrieveGlobalIndexedPointersMap(const TContainerType &rContainer, const std::vector< int > &rIdList, const DataCommunicator &rDataCommunicator)
Retrieves a map of global pointers corresponding to the given entity ids, where the global pointers p...
Definition: global_pointer_utilities.h:95
static GlobalPointersVector< typename TContainerType::value_type > RetrieveGlobalIndexedPointers(const TContainerType &rContainer, const std::vector< int > &rIdList, const DataCommunicator &rDataCommunicator)
Retrieve global indexed pointers from container and data communicator.
Definition: global_pointer_utilities.h:329
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
Definition: debug_utilities.h:36
typename std::enable_if< is_kratos_bounded_vector_variable< TVarType >::value, TReturnType >::type EnalbeIfBoundedVector
Definition: debug_utilities.h:51
static void CheckNonHistoricalVariable(ModelPart &rModelPart, const TContainerType &rContainer, const TVarType &rVariable)
Definition: debug_utilities.h:95
MpiDebugUtilities()
Definition: debug_utilities.h:41
static EnalbeIfSingle< TVarType, bool > InteralCmpEq(const TVarType &rVar1, const TVarType &rVar2)
Definition: debug_utilities.h:80
static void CheckHistoricalVariable(ModelPart &rModelPart, const TVarType &rVariable)
Definition: debug_utilities.h:160
typename std::enable_if< is_kratos_single_variable< TVarType >::value, TReturnType >::type EnalbeIfSingle
Definition: debug_utilities.h:50
typename std::enable_if< is_kratos_unbounded_vector_variable< TVarType >::value, TReturnType >::type EnalbeIfUnbounedVector
Definition: debug_utilities.h:52
KRATOS_CLASS_POINTER_DEFINITION(MpiDebugUtilities)
static void CheckHistoricalVariable(ModelPart &rModelPart, const TVarType &rVariable, GlobalPointerCommunicator< Node > &rPointerCommunicator, std::unordered_map< int, GlobalPointer< Node >> &gp_map)
Definition: debug_utilities.h:183
static void CheckNonHistoricalVariable(ModelPart &rModelPart, const TContainerType &rContainer, const TVarType &rVariable, GlobalPointerCommunicator< typename TContainerType::data_type > &rPointerCommunicator, std::unordered_map< int, GlobalPointer< typename TContainerType::data_type >> &gp_map)
Definition: debug_utilities.h:117
static EnalbeIfBoundedVector< TVarType, bool > InteralCmpEq(const TVarType &rVar1, const TVarType &rVar2)
Definition: debug_utilities.h:86
static DataCommunicator & GetDefaultDataCommunicator()
Retrieve the default DataCommunicator instance.
Definition: parallel_environment.cpp:32
#define KRATOS_ERROR
Definition: exception.h:161
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
type
Definition: generate_gid_list_file.py:35
list node_list
Definition: mesh_to_mdpa_converter.py:39
integer i
Definition: TensorModule.f:17
Definition: debug_utilities.h:44
Definition: mesh_converter.cpp:38