singleProcessorFaceSetsConstraint.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2015-2016 OpenFOAM Foundation
9  Copyright (C) 2018-2019 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
31 #include "syncTools.H"
32 #include "faceSet.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 namespace decompositionConstraints
39 {
40  defineTypeName(singleProcessorFaceSets);
41 
43  (
44  decompositionConstraint,
45  singleProcessorFaceSets,
46  dictionary
47  );
48 }
49 }
50 
51 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
52 
53 void Foam::decompositionConstraints::singleProcessorFaceSets::printInfo() const
54 {
55  for (const auto& nameAndProc : setNameAndProcs_)
56  {
57  Info<< " all cells connected to faceSet "
58  << nameAndProc.first()
59  << " on processor " << nameAndProc.second() << endl;
60  }
61 }
62 
63 
64 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
65 
68 (
69  const dictionary& dict
70 )
71 :
72  decompositionConstraint(dict, typeName),
73  setNameAndProcs_
74  (
75  coeffDict_.lookupCompat("sets", {{"singleProcessorFaceSets", 1806}})
76  )
77 {
79  {
80  Info<< type()
81  << " : adding constraints to keep" << endl;
82 
83  printInfo();
84  }
85 }
86 
87 
90 (
91  const List<Tuple2<word, label>>& setNameAndProcs
92 )
93 :
95  setNameAndProcs_(setNameAndProcs)
96 {
98  {
99  Info<< type()
100  << " : adding constraints to keep" << endl;
101 
102  printInfo();
103  }
104 }
105 
106 
109 (
110  Istream& is
111 )
112 :
113  decompositionConstraint(dictionary(), typeName),
114  setNameAndProcs_(is)
115 {
117  {
118  Info<< type()
119  << " : adding constraints to keep" << endl;
120 
121  printInfo();
122  }
123 }
124 
125 
126 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
127 
129 (
130  const polyMesh& mesh,
131  boolList& blockedFace,
132  PtrList<labelList>& specifiedProcessorFaces,
133  labelList& specifiedProcessor,
134  List<labelPair>& explicitConnections
135 ) const
136 {
137  blockedFace.resize(mesh.nFaces(), true);
138 
139  // Mark faces already in set
140  labelList faceToSet(mesh.nFaces(), -1);
141  forAll(specifiedProcessorFaces, setI)
142  {
143  const labelList& faceLabels = specifiedProcessorFaces[setI];
144  for (const label facei : faceLabels)
145  {
146  faceToSet[facei] = setI;
147  }
148  }
149 
150  forAll(setNameAndProcs_, setI)
151  {
152  //Info<< "Keeping all cells connected to faceSet "
153  // << setNameAndProcs_[setI].first()
154  // << " on processor " << setNameAndProcs_[setI].second() << endl;
155 
156  const label destProcI = setNameAndProcs_[setI].second();
157 
158  // Read faceSet
159  const faceSet fz(mesh, setNameAndProcs_[setI].first());
160 
161  // Check that it does not overlap with existing specifiedProcessorFaces
162  labelList nMatch(specifiedProcessorFaces.size(), Zero);
163  for (const label facei : fz)
164  {
165  const label seti = faceToSet[facei];
166  if (seti != -1)
167  {
168  ++nMatch[seti];
169  }
170  }
171 
172 
173  // Only store if all faces are not yet in specifiedProcessorFaces
174  // (on all processors)
175  bool store = true;
176 
177  forAll(nMatch, setI)
178  {
179  if (nMatch[setI] == fz.size())
180  {
181  // Full match
182  store = false;
183  break;
184  }
185  else if (nMatch[setI] > 0)
186  {
187  // Partial match
188  store = false;
189  break;
190  }
191  }
192 
193  reduce(store, andOp<bool>());
194 
195  if (store)
196  {
197  specifiedProcessorFaces.append(new labelList(fz.sortedToc()));
198  specifiedProcessor.append(destProcI);
199  }
200  }
201 
202 
203  // Unblock all point connected faces
204  // 1. Mark all points on specifiedProcessorFaces
205  boolList procFacePoint(mesh.nPoints(), false);
206  forAll(specifiedProcessorFaces, setI)
207  {
208  const labelList& faceLabels = specifiedProcessorFaces[setI];
209  for (const label facei : faceLabels)
210  {
211  const face& f = mesh.faces()[facei];
212 
213  for (const label pointi : f)
214  {
215  procFacePoint[pointi] = true;
216  }
217  }
218  }
219  syncTools::syncPointList(mesh, procFacePoint, orEqOp<bool>(), false);
220 
221  // 2. Unblock all faces on procFacePoint
222 
223  label nUnblocked = 0;
224 
225  forAll(procFacePoint, pointi)
226  {
227  if (procFacePoint[pointi])
228  {
229  const labelList& pFaces = mesh.pointFaces()[pointi];
230  forAll(pFaces, i)
231  {
232  if (blockedFace[pFaces[i]])
233  {
234  blockedFace[pFaces[i]] = false;
235  ++nUnblocked;
236  }
237  }
238  }
239  }
240 
242  {
243  reduce(nUnblocked, sumOp<label>());
244  Info<< type() << " : unblocked " << nUnblocked << " faces" << endl;
245  }
246 
247  syncTools::syncFaceList(mesh, blockedFace, andEqOp<bool>());
248 }
249 
250 
252 (
253  const polyMesh& mesh,
254  const boolList& blockedFace,
255  const PtrList<labelList>& specifiedProcessorFaces,
256  const labelList& specifiedProcessor,
257  const List<labelPair>& explicitConnections,
258  labelList& decomposition
259 ) const
260 {
261  // For specifiedProcessorFaces rework the cellToProc to enforce
262  // all on one processor since we can't guarantee that the input
263  // to regionSplit was a single region.
264  // E.g. faceSet 'a' with the cells split into two regions
265  // by a notch formed by two walls
266  //
267  // \ /
268  // \ /
269  // ---a----+-----a-----
270  //
271  //
272  // Note that reworking the cellToProc might make the decomposition
273  // unbalanced.
274  label nChanged = 0;
275 
276  forAll(specifiedProcessorFaces, setI)
277  {
278  const labelList& set = specifiedProcessorFaces[setI];
279 
280  // Get the processor to use for the set
281  label procI = specifiedProcessor[setI];
282  if (procI == -1)
283  {
284  // If no processor specified use the one from the
285  // 0th element
286  if (set.size())
287  {
288  procI = decomposition[mesh.faceOwner()[set[0]]];
289  }
290  reduce(procI, maxOp<label>());
291  }
292 
293  // Get all points on the sets
294  boolList procFacePoint(mesh.nPoints(), false);
295  forAll(set, fI)
296  {
297  const face& f = mesh.faces()[set[fI]];
298  forAll(f, fp)
299  {
300  procFacePoint[f[fp]] = true;
301  }
302  }
303  syncTools::syncPointList(mesh, procFacePoint, orEqOp<bool>(), false);
304 
305  // 2. Unblock all faces on procFacePoint
306  forAll(procFacePoint, pointi)
307  {
308  if (procFacePoint[pointi])
309  {
310  const labelList& pFaces = mesh.pointFaces()[pointi];
311  for (const label faceI : pFaces)
312  {
313  const label own = mesh.faceOwner()[faceI];
314 
315  if (decomposition[own] != procI)
316  {
317  decomposition[own] = procI;
318  ++nChanged;
319  }
320 
321  if (mesh.isInternalFace(faceI))
322  {
323  const label nei = mesh.faceNeighbour()[faceI];
324  if (decomposition[nei] != procI)
325  {
326  decomposition[nei] = procI;
327  ++nChanged;
328  }
329  }
330  }
331  }
332  }
333  }
334 
336  {
337  reduce(nChanged, sumOp<label>());
338  Info<< type() << " : changed decomposition on " << nChanged
339  << " cells" << endl;
340  }
341 }
342 
343 
344 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::maxOp
Definition: ops.H:223
Foam::decompositionConstraint
Abstract class for handling decomposition constraints.
Definition: decompositionConstraint.H:58
Foam::BitOps::set
void set(List< bool > &bools, const labelRange &range)
Set the specified range 'on' in a boolList.
Definition: BitOps.C:37
Foam::decompositionConstraints::defineTypeName
defineTypeName(geometric)
Foam::List::resize
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::andEqOp
Definition: ops.H:85
Foam::faceSet
A list of face labels.
Definition: faceSet.H:51
Foam::orEqOp
Definition: ops.H:86
Foam::List::append
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:175
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
syncTools.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::syncTools::syncPointList
static void syncPointList(const polyMesh &mesh, List< T > &pointValues, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh points.
Definition: syncToolsTemplates.C:721
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::syncTools::syncFaceList
static void syncFaceList(const polyMesh &mesh, UList< T > &faceValues, const CombineOp &cop)
Synchronize values on all mesh faces.
Definition: syncTools.H:396
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::decompositionConstraints::singleProcessorFaceSets::singleProcessorFaceSets
singleProcessorFaceSets(const dictionary &dict)
Construct with constraint dictionary.
Definition: singleProcessorFaceSetsConstraint.C:68
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
faceSet.H
Foam::andOp
Definition: ops.H:233
singleProcessorFaceSetsConstraint.H
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:59
Foam::PtrList::append
void append(T *ptr)
Append an element to the end of the list.
Definition: PtrListI.H:113
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::decompositionConstraints::singleProcessorFaceSets::add
virtual void add(const polyMesh &mesh, boolList &blockedFace, PtrList< labelList > &specifiedProcessorFaces, labelList &specifiedProcessor, List< labelPair > &explicitConnections) const
Add this constraint to list of constraints.
Definition: singleProcessorFaceSetsConstraint.C:129
Foam::decompositionConstraints::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionConstraint, geometric, dictionary)
f
labelList f(nPoints)
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::decompositionConstraints::singleProcessorFaceSets::apply
virtual void apply(const polyMesh &mesh, const boolList &blockedFace, const PtrList< labelList > &specifiedProcessorFaces, const labelList &specifiedProcessor, const List< labelPair > &explicitConnections, labelList &decomposition) const
Add this constraint post-decomposition.
Definition: singleProcessorFaceSetsConstraint.C:252
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::Tuple2
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: stringOps.H:60
pFaces
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::HEX);labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells].reset(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};const label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< SLList< face > > pFaces[nBCs]
Definition: readKivaGrid.H:235