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 | Copyright (C) 2015 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 
28 #include "syncTools.H"
29 #include "faceSet.H"
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35 namespace decompositionConstraints
36 {
39 (
40  decompositionConstraint,
42  dictionary
43 );
44 }
45 }
46 
47 
48 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49 
52 (
53  const dictionary& constraintsDict,
54  const word& modelType
55 )
56 :
57  decompositionConstraint(constraintsDict, typeName),
58  setNameAndProcs_(coeffDict_.lookup("singleProcessorFaceSets"))
59 {
60  if (decompositionConstraint::debug)
61  {
62  Info<< type()
63  << " : adding constraints to keep" << endl;
64 
65  forAll(setNameAndProcs_, setI)
66  {
67  Info<< " all cells connected to faceSet "
68  << setNameAndProcs_[setI].first()
69  << " on processor " << setNameAndProcs_[setI].second() << endl;
70  }
71  }
72 }
73 
74 
77 (
78  const List<Tuple2<word, label> >& setNameAndProcs
79 )
80 :
82  setNameAndProcs_(setNameAndProcs)
83 {
84  if (decompositionConstraint::debug)
85  {
86  Info<< type()
87  << " : adding constraints to keep" << endl;
88 
89  forAll(setNameAndProcs_, setI)
90  {
91  Info<< " all cells connected to faceSet "
92  << setNameAndProcs_[setI].first()
93  << " on processor " << setNameAndProcs_[setI].second() << endl;
94  }
95  }
96 }
97 
98 
99 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
100 
102 (
103  const polyMesh& mesh,
104  boolList& blockedFace,
105  PtrList<labelList>& specifiedProcessorFaces,
106  labelList& specifiedProcessor,
107  List<labelPair>& explicitConnections
108 ) const
109 {
110  blockedFace.setSize(mesh.nFaces(), true);
111 
112  // Mark faces already in set
113  labelList faceToSet(mesh.nFaces(), -1);
114  forAll(specifiedProcessorFaces, setI)
115  {
116  const labelList& faceLabels = specifiedProcessorFaces[setI];
117  forAll(faceLabels, i)
118  {
119  faceToSet[faceLabels[i]] = setI;
120  }
121  }
122 
123 
124  forAll(setNameAndProcs_, setI)
125  {
126  //Info<< "Keeping all cells connected to faceSet "
127  // << setNameAndProcs_[setI].first()
128  // << " on processor " << setNameAndProcs_[setI].second() << endl;
129 
130  const label destProcI = setNameAndProcs_[setI].second();
131 
132  // Read faceSet
133  const faceSet fz(mesh, setNameAndProcs_[setI].first());
134 
135  // Check that it does not overlap with existing specifiedProcessorFaces
136  labelList nMatch(specifiedProcessorFaces.size(), 0);
137  forAllConstIter(faceSet, fz, iter)
138  {
139  label setI = faceToSet[iter.key()];
140  if (setI != -1)
141  {
142  nMatch[setI]++;
143  }
144  }
145 
146 
147  // Only store if all faces are not yet in specifiedProcessorFaces
148  // (on all processors)
149  bool store = true;
150 
151  forAll(nMatch, setI)
152  {
153  if (nMatch[setI] == fz.size())
154  {
155  // full match
156  store = false;
157  break;
158  }
159  else if (nMatch[setI] > 0)
160  {
161  // partial match
162  store = false;
163  break;
164  }
165  }
166 
167  reduce(store, andOp<bool>());
168 
169 
170  if (store)
171  {
172  specifiedProcessorFaces.append(new labelList(fz.sortedToc()));
173  specifiedProcessor.append(destProcI);
174  }
175  }
176 
177 
178  // Unblock all point connected faces
179  // 1. Mark all points on specifiedProcessorFaces
180  boolList procFacePoint(mesh.nPoints(), false);
181  forAll(specifiedProcessorFaces, setI)
182  {
183  const labelList& set = specifiedProcessorFaces[setI];
184  forAll(set, fI)
185  {
186  const face& f = mesh.faces()[set[fI]];
187  forAll(f, fp)
188  {
189  procFacePoint[f[fp]] = true;
190  }
191  }
192  }
193  syncTools::syncPointList(mesh, procFacePoint, orEqOp<bool>(), false);
194 
195  // 2. Unblock all faces on procFacePoint
196 
197  label nUnblocked = 0;
198 
199  forAll(procFacePoint, pointI)
200  {
201  if (procFacePoint[pointI])
202  {
203  const labelList& pFaces = mesh.pointFaces()[pointI];
204  forAll(pFaces, i)
205  {
206  if (blockedFace[pFaces[i]])
207  {
208  blockedFace[pFaces[i]] = false;
209  nUnblocked++;
210  }
211  }
212  }
213  }
214 
215  if (decompositionConstraint::debug & 2)
216  {
217  reduce(nUnblocked, sumOp<label>());
218  Info<< type() << " : unblocked " << nUnblocked << " faces" << endl;
219  }
220 
221  syncTools::syncFaceList(mesh, blockedFace, andEqOp<bool>());
222 }
223 
224 
226 (
227  const polyMesh& mesh,
228  const boolList& blockedFace,
229  const PtrList<labelList>& specifiedProcessorFaces,
230  const labelList& specifiedProcessor,
231  const List<labelPair>& explicitConnections,
232  labelList& decomposition
233 ) const
234 {
235  // For specifiedProcessorFaces rework the cellToProc to enforce
236  // all on one processor since we can't guarantee that the input
237  // to regionSplit was a single region.
238  // E.g. faceSet 'a' with the cells split into two regions
239  // by a notch formed by two walls
240  //
241  // \ /
242  // \ /
243  // ---a----+-----a-----
244  //
245  //
246  // Note that reworking the cellToProc might make the decomposition
247  // unbalanced.
248  label nChanged = 0;
249 
250  forAll(specifiedProcessorFaces, setI)
251  {
252  const labelList& set = specifiedProcessorFaces[setI];
253 
254  // Get the processor to use for the set
255  label procI = specifiedProcessor[setI];
256  if (procI == -1)
257  {
258  // If no processor specified use the one from the
259  // 0th element
260  if (set.size())
261  {
262  procI = decomposition[mesh.faceOwner()[set[0]]];
263  }
264  reduce(procI, maxOp<label>());
265  }
266 
267  // Get all points on the sets
268  boolList procFacePoint(mesh.nPoints(), false);
269  forAll(set, fI)
270  {
271  const face& f = mesh.faces()[set[fI]];
272  forAll(f, fp)
273  {
274  procFacePoint[f[fp]] = true;
275  }
276  }
277  syncTools::syncPointList(mesh, procFacePoint, orEqOp<bool>(), false);
278 
279  // 2. Unblock all faces on procFacePoint
280  forAll(procFacePoint, pointI)
281  {
282  if (procFacePoint[pointI])
283  {
284  const labelList& pFaces = mesh.pointFaces()[pointI];
285  forAll(pFaces, i)
286  {
287  label faceI = pFaces[i];
288 
289  label own = mesh.faceOwner()[faceI];
290  if (decomposition[own] != procI)
291  {
292  decomposition[own] = procI;
293  nChanged++;
294  }
295  if (mesh.isInternalFace(faceI))
296  {
297  label nei = mesh.faceNeighbour()[faceI];
298  if (decomposition[nei] != procI)
299  {
300  decomposition[nei] = procI;
301  nChanged++;
302  }
303  }
304  }
305  }
306  }
307  }
308 
309  if (decompositionConstraint::debug & 2)
310  {
311  reduce(nChanged, sumOp<label>());
312  Info<< type() << " : changed decomposition on " << nChanged
313  << " cells" << endl;
314  }
315 }
316 
317 
318 // ************************************************************************* //
Foam::decompositionConstraints::singleProcessorFaceSetsConstraint::add
virtual void add(const polyMesh &mesh, boolList &blockedFace, PtrList< labelList > &specifiedProcessorFaces, labelList &specifiedProcessor, List< labelPair > &explicitConnections) const
Add my constraints to list of constraints.
Definition: singleProcessorFaceSetsConstraint.C:102
Foam::maxOp
Definition: ops.H:172
Foam::decompositionConstraints::singleProcessorFaceSetsConstraint::singleProcessorFaceSetsConstraint
singleProcessorFaceSetsConstraint(const dictionary &constraintsDict, const word &type)
Construct with generic dictionary with optional entry for type.
Definition: singleProcessorFaceSetsConstraint.C:52
Foam::decompositionConstraint
Definition: decompositionConstraint.H:54
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::labelList
List< label > labelList
A List of labels.
Definition: labelList.H:56
Foam::PtrList::append
void append(T *)
Append an element at the end of the list.
Foam::decompositionConstraints::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionConstraint, preserveBafflesConstraint, dictionary)
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::decompositionConstraints::defineTypeName
defineTypeName(preserveBafflesConstraint)
Foam::faceSet
A list of face labels.
Definition: faceSet.H:48
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
syncTools.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
forAllConstIter
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
pFaces
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=*(cellModeller::lookup("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]=cellShape(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
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:43
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::List::append
void append(const T &)
Append an element at the end of the list.
Foam::Info
messageStream Info
faceSet.H
singleProcessorFaceSetsConstraint.H
Foam::PtrList
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:61
Foam::orEqOp
Definition: ops.H:82
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
Foam::HashTable::size
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::HashTable::sortedToc
List< Key > sortedToc() const
Return the table of contents as a sorted list.
Definition: HashTable.C:216
singleProcessorFaceSetsConstraint
Constraint to keep all cells connected to face or point of faceSet on a single processor.
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::andOp
Definition: ops.H:177
Foam::sumOp
Definition: ops.H:162
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: HashTable.H:59
Foam::PtrList::size
label size() const
Return the number of elements in the PtrList.
Definition: PtrListI.H:32
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::Tuple2
A 2-tuple for storing two objects of different types.
Definition: Tuple2.H:47
Foam::type
fileName::Type type(const fileName &)
Return the file type: DIRECTORY or FILE.
Definition: POSIX.C:588
Foam::decompositionConstraints::singleProcessorFaceSetsConstraint::apply
virtual void apply(const polyMesh &mesh, const boolList &blockedFace, const PtrList< labelList > &specifiedProcessorFaces, const labelList &specifiedProcessor, const List< labelPair > &explicitConnections, labelList &decomposition) const
Apply any additional post-decomposition constraints.
Definition: singleProcessorFaceSetsConstraint.C:226
Foam::andEqOp
Definition: ops.H:81