zoltanRenumber.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "zoltanRenumber.H"
28 #include "IFstream.H"
29 #include "labelIOList.H"
30 #include "polyMesh.H"
31 #include "globalMeshData.H"
32 #include "globalIndex.H"
33 #include "uint.H"
34 #include "PstreamGlobals.H"
35 
36 #include "zoltan.h"
37 
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42  defineTypeNameAndDebug(zoltanRenumber, 0);
43 
45  (
46  renumberMethod,
47  zoltanRenumber,
48  dictionary
49  );
50 }
51 
52 
53 static int get_number_of_vertices(void *data, int *ierr)
54 {
55  const Foam::polyMesh& mesh = *static_cast<const Foam::polyMesh*>(data);
56 
57  *ierr = ZOLTAN_OK;
58 
59  return mesh.nCells();
60 }
61 
62 
63 static void get_vertex_list
64 (
65  void* data,
66  int nGID,
67  int nLID,
68  ZOLTAN_ID_PTR globalIDs,
69  ZOLTAN_ID_PTR localIDs,
70  int wgt_dim,
71  float* obj_wgts,
72  int* ierr
73 )
74 {
75  const Foam::polyMesh& mesh = *static_cast<const Foam::polyMesh*>(data);
76 
77  // In this example, return the IDs of our vertices, but no weights.
78  // Zoltan will assume equally weighted vertices.
79 
80  // Global calculation engine
81  Foam::globalIndex globalCellMap(mesh.nCells());
82 
83  for (Foam::label i=0; i<mesh.nCells(); i++)
84  {
85  localIDs[i] = i;
86  globalIDs[i] = globalCellMap.toGlobal(i);
87  }
88 
89  *ierr = ZOLTAN_OK;
90 }
91 
92 
93 static int get_mesh_dim(void* data, int* ierr)
94 {
95  const Foam::polyMesh& mesh = *static_cast<const Foam::polyMesh*>(data);
96 
97  return mesh.nSolutionD();
98 }
99 
100 
101 static void get_geom_list
102 (
103  void* data,
104  int nGID,
105  int nLID,
106  int nCells,
107  ZOLTAN_ID_PTR globalIDs,
108  ZOLTAN_ID_PTR localIDs,
109  int nDim,
110  double* cellCentres,
111  int* ierr
112 )
113 {
114  const Foam::polyMesh& mesh = *static_cast<const Foam::polyMesh*>(data);
115 
116  if
117  (
118  (nGID != 1)
119  || (nLID != 1)
120  || (nCells != mesh.nCells())
121  || (nDim != mesh.nSolutionD())
122  )
123  {
124  *ierr = ZOLTAN_FATAL;
125  return;
126  }
127 
128  double* p = cellCentres;
129 
130  const Foam::Vector<Foam::label>& sol = mesh.solutionD();
131  const Foam::pointField& cc = mesh.cellCentres();
132 
133  for (Foam::label celli=0; celli<nCells; celli++)
134  {
135  const Foam::point& pt = cc[celli];
136 
137  for (Foam::direction cmpt=0; cmpt<Foam::vector::nComponents; cmpt++)
138  {
139  if (sol[cmpt] == 1)
140  {
141  *p++ = pt[cmpt];
142  }
143  }
144  }
145 
146  *ierr = ZOLTAN_OK;
147 }
148 
149 
150 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
151 
153 :
154  renumberMethod(renumberDict)
155 {}
156 
157 
158 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
159 
161 (
162  const polyMesh& mesh,
163  const pointField& points
164 ) const
165 {
166  stringList args(1);
167  args[0] = "zoltanRenumber";
168 
169  int argc = args.size();
170  char* argv[argc];
171  for (label i = 0; i < argc; i++)
172  {
173  argv[i] = strdup(args[i].c_str());
174  }
175 
176  float ver;
177  int rc = Zoltan_Initialize(argc, argv, &ver);
178 
179  if (rc != ZOLTAN_OK)
180  {
182  << "Failed initialising Zoltan" << exit(FatalError);
183  }
184 
185  struct Zoltan_Struct *zz = Zoltan_Create(PstreamGlobals::MPI_COMM_FOAM);
186 
187  {
188  // Set default order method to LOCAL_HSFC
189  Zoltan_Set_Param(zz, "ORDER_METHOD", "LOCAL_HSFC");
190  Zoltan_Set_Param(zz, "ORDER_TYPE", "LOCAL");
191 
192  forAllConstIter(IDLList<entry>, coeffsDict_, iter)
193  {
194  if (!iter().isDict())
195  {
196  const word& key = iter().keyword();
197  const word value(iter().stream());
198 
199  Info<< typeName << " : setting parameter " << key
200  << " to " << value << endl;
201 
202  Zoltan_Set_Param(zz, key.c_str(), value.c_str());
203  }
204  }
205 
206  void* meshPtr = &const_cast<polyMesh&>(mesh);
207 
208  Zoltan_Set_Num_Obj_Fn(zz, get_number_of_vertices, meshPtr);
209  Zoltan_Set_Obj_List_Fn(zz, get_vertex_list, meshPtr);
210 
211  // Callbacks for geometry
212  Zoltan_Set_Num_Geom_Fn(zz, get_mesh_dim, meshPtr);
213  Zoltan_Set_Geom_Multi_Fn(zz, get_geom_list, meshPtr);
214  }
215 
216  // Local to global cell index mapper
217  globalIndex globalCellMap(mesh.nCells());
218 
219  List<ZOLTAN_ID_TYPE> globalCells(mesh.nCells());
220  forAll(globalCells, i)
221  {
222  globalCells[i] = globalCellMap.toGlobal(i);
223  }
224 
225  // Old local to new global cell index map
226  // Values set by Zoltan_Order
227  List<ZOLTAN_ID_TYPE> oldToNew(mesh.nCells());
228 
229  // Call Zoltan to reorder the cells
230  int err = Zoltan_Order
231  (
232  zz,
233  1, // int nGID,
234  mesh.nCells(),
235  globalCells.begin(),
236  oldToNew.begin()
237  );
238 
239  // Check for Zoltan errors
240  if (err != ZOLTAN_OK)
241  {
243  << "Failed Zoltan_Order" << exit(FatalError);
244  }
245 
246  // Free the argv array
247  for (label i = 0; i < argc; i++)
248  {
249  free(argv[i]);
250  }
251 
252  // Free the Zoltan_Struct allocated by Zoltan_Create
253  Zoltan_Destroy(&zz);
254 
255  // Map the oldToNew global cell indices to local
256  labelList order(oldToNew.size());
257  forAll(order, i)
258  {
259  order[i] = globalCellMap.toLocal(oldToNew[i]);
260  }
261 
262  return order;
263 }
264 
265 
266 // ************************************************************************* //
Template class for intrusive linked lists.
Definition: ILList.H:50
static int get_mesh_dim(void *data, int *ierr)
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:156
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:477
static fvMesh * meshPtr
Definition: globalFoam.H:52
uint8_t direction
Definition: direction.H:45
const Vector< label > & solutionD() const
Return the vector of solved-for directions in mesh.
Definition: polyMesh.C:911
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
label nCells() const
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
virtual labelList renumber(const pointField &) const
Return the order in which cells need to be visited, i.e.
static void get_geom_list(void *data, int nGID, int nLID, int nCells, ZOLTAN_ID_PTR globalIDs, ZOLTAN_ID_PTR localIDs, int nDim, double *cellCentres, int *ierr)
fvMesh & mesh
static void get_vertex_list(void *data, int nGID, int nLID, ZOLTAN_ID_PTR globalIDs, ZOLTAN_ID_PTR localIDs, int wgt_dim, float *obj_wgts, int *ierr)
Macros for easy insertion into run-time selection tables.
Abstract base class for renumbering.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
static const direction nComponents
Number of components in this vector space.
Definition: VectorSpace.H:99
System uinteger.
A class for handling words, derived from string.
Definition: word.H:59
const vectorField & cellCentres() const
Templated 3D Vector derived from VectorSpace adding construction from 3 components, element access using x(), y() and z() member functions and the inner-product (dot-product) and cross product operators.
Definition: Vector.H:57
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
defineTypeNameAndDebug(combustionModel, 0)
static int get_number_of_vertices(void *data, int *ierr)
label nSolutionD() const
Return the number of valid solved-for dimensions in the mesh.
Definition: polyMesh.C:922
label toGlobal(const label i) const
From local to global.
Definition: globalIndexI.H:82
zoltanRenumber(const dictionary &renumberDict)
Construct given the renumber dictionary.
messageStream Info
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:76
volScalarField & p
Foam::argList args(argc, argv)
Namespace for OpenFOAM.