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.
reorder_and_optimize_modelpart_process.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 //
12 //
13 
14 #if !defined(KRATOS_REORDER_AND_OPTIMIZE_MODELPART_PROCESS_H_INCLUDED )
15 #define KRATOS_REORDER_AND_OPTIMIZE_MODELPART_PROCESS_H_INCLUDED
16 
17 // System includes
18 #include <string>
19 #include <iostream>
20 
21 // External includes
22 
23 // Project includes
24 #include "processes/process.h"
25 #include "includes/model_part.h"
28 
29 namespace Kratos
30 {
33 
36 
38 
40 class KRATOS_API(KRATOS_CORE) ReorderAndOptimizeModelPartProcess : public Process
41 {
42 public:
46 
49 
53 
56 
59 
62 
65 
69 
72 
76 
77  void Execute() override;
78 
79 
83 
84 
88 
89 
93 
95  std::string Info() const override;
96 
98  void PrintInfo(std::ostream& rOStream) const override;
99 
101  void PrintData(std::ostream& rOStream) const override;
102 
103 
107 
108 
110 
111 protected:
114 
115 
120 
121 
125  void ActualizeSubModelPart(ModelPart& subpart);
126  void OptimizeOrdering();
127  void ReorderElements();
128 
132 
133 
137 
138  template <bool reverse = false>
140  {
141  template <class Matrix>
142  static void get(const Matrix &A, std::vector<int>& invperm)
143  {
144  const int n = A.size1();
145  std::vector<int> perm(n);
146 
147  /* The data structure used to sort and traverse the level sets:
148  *
149  * The current level set is currentLevelSet;
150  * In this level set, there are nodes with degrees from 0 (not really
151  * useful) to maxDegreeInCurrentLevelSet.
152  * firstWithDegree[i] points to a node with degree i, or to -1 if it
153  * does not exist. nextSameDegree[firstWithDegree[i]] points to the
154  * second node with that degree, etc.
155  * While the level set is being traversed, the structure for the next
156  * level set is generated; nMDICLS will be the next
157  * maxDegreeInCurrentLevelSet and nFirstWithDegree will be
158  * firstWithDegree.
159  */
160  int initialNode = 0; // node to start search
161  int maxDegree = 0;
162 
163  std::vector<int> degree(n);
164  std::vector<int> levelSet(n, 0);
165  std::vector<int> nextSameDegree(n, -1);
166 
167  for(int i = 0; i < n; ++i)
168  {
169  degree[i] = A.index1_data()[i+1] - A.index1_data()[i]; //backend::row_nonzeros(A, i);
170  maxDegree = std::max(maxDegree, degree[i]);
171  }
172 
173  std::vector<int> firstWithDegree(maxDegree + 1, -1);
174  std::vector<int> nFirstWithDegree(maxDegree + 1);
175 
176  // Initialize the first level set, made up by initialNode alone
177  perm[0] = initialNode;
178  int currentLevelSet = 1;
179  levelSet[initialNode] = currentLevelSet;
180  int maxDegreeInCurrentLevelSet = degree[initialNode];
181  firstWithDegree[maxDegreeInCurrentLevelSet] = initialNode;
182 
183  // Main loop
184  for (int next = 1; next < n; )
185  {
186  int nMDICLS = 0;
187  std::fill(nFirstWithDegree.begin(), nFirstWithDegree.end(), -1);
188  bool empty = true; // used to detect different connected components
189 
190  int firstVal = reverse ? maxDegreeInCurrentLevelSet : 0;
191  int finalVal = reverse ? -1 : maxDegreeInCurrentLevelSet + 1;
192  int increment = reverse ? -1 : 1;
193 
194  for(int soughtDegree = firstVal; soughtDegree != finalVal; soughtDegree += increment)
195  {
196  int node = firstWithDegree[soughtDegree];
197  while (node > 0)
198  {
199  // Visit neighbors
200  for(auto a = A.index1_data()[node] /*backend::row_begin(A, node)*/; a<A.index1_data()[node+1]; ++a)
201  {
202  int c = A.index2_data()[a]; //a.col();
203  if (levelSet[c] == 0)
204  {
205  levelSet[c] = currentLevelSet + 1;
206  perm[next] = c;
207  ++next;
208  empty = false; // this level set is not empty
209  nextSameDegree[c] = nFirstWithDegree[degree[c]];
210  nFirstWithDegree[degree[c]] = c;
211  nMDICLS = std::max(nMDICLS, degree[c]);
212  }
213  }
214  node = nextSameDegree[node];
215  }
216  }
217 
218  ++currentLevelSet;
219  maxDegreeInCurrentLevelSet = nMDICLS;
220  for(int i = 0; i <= nMDICLS; ++i)
221  firstWithDegree[i] = nFirstWithDegree[i];
222 
223  if (empty)
224  {
225  // The graph contains another connected component that we
226  // cannot reach. Search for a node that has not yet been
227  // included in a level set, and start exploring from it.
228  for(int i = 0; i < n; ++i)
229  {
230  if (levelSet[i] == 0)
231  {
232  perm[next] = i;
233  ++next;
234  levelSet[i] = currentLevelSet;
235  maxDegreeInCurrentLevelSet = degree[i];
236  firstWithDegree[maxDegreeInCurrentLevelSet] = i;
237  break;
238  }
239  }
240  }
241  }
242 
243  //computing the inverse permutation
244  IndexPartition<std::size_t>(n).for_each([&] (std::size_t Index){
245  invperm[perm[Index]] = Index;
246  });
247 
248  }
249  };
250 
254 
255 
256 
258 
259 }; // Class ReorderAndOptimizeModelPartProcess
260 
262 
265 
266 
270 
271 
273 inline std::istream& operator >> (std::istream& rIStream,
275 
277 inline std::ostream& operator << (std::ostream& rOStream,
279 {
280  rThis.PrintInfo(rOStream);
281  rOStream << std::endl;
282  rThis.PrintData(rOStream);
283 
284  return rOStream;
285 }
287 
289 
290 } // namespace Kratos.
291 
292 #endif // KRATOS_REORDER_AND_OPTIMIZE_MODELPART_PROCESS_H_INCLUDED defined
std::string Info() const override
Turn back information as a string.
Definition: periodic_interface_process.hpp:93
Geometry base class.
Definition: geometry.h:71
This class is useful for index iteration over containers.
Definition: parallel_utilities.h:451
void for_each(TUnaryFunction &&f)
Definition: parallel_utilities.h:514
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
The base class for all processes in Kratos.
Definition: process.h:49
Short class definition.
Definition: reorder_and_optimize_modelpart_process.h:41
ModelPart & mrModelPart
Definition: reorder_and_optimize_modelpart_process.h:119
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: reorder_and_optimize_modelpart_process.cpp:248
ReorderAndOptimizeModelPartProcess(ReorderAndOptimizeModelPartProcess const &rOther)=delete
The object is not copyable.
KRATOS_CLASS_POINTER_DEFINITION(ReorderAndOptimizeModelPartProcess)
Pointer definition of ReorderAndOptimizeModelPartProcess.
~ReorderAndOptimizeModelPartProcess() override
Destructor.
Definition: reorder_and_optimize_modelpart_process.h:64
ReorderAndOptimizeModelPartProcess()=delete
Default constructor is deleted.
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: reorder_and_optimize_modelpart_process.cpp:243
ReorderAndOptimizeModelPartProcess & operator=(ReorderAndOptimizeModelPartProcess const &rOther)=delete
It is not assignable.
static double max(double a, double b)
Definition: GeometryFunctions.h:79
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
a
Definition: generate_stokes_twofluid_element.py:77
c
Definition: generate_weakly_compressible_navier_stokes_element.py:108
def Index()
Definition: hdf5_io_tools.py:38
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
A
Definition: sensitivityMatrix.py:70
integer i
Definition: TensorModule.f:17
Definition: reorder_and_optimize_modelpart_process.h:140
static void get(const Matrix &A, std::vector< int > &invperm)
Definition: reorder_and_optimize_modelpart_process.h:142
Definition: mesh_converter.cpp:38