fvMeshPrimitiveLduAddressing.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-2017 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
29 #include "lduPrimitiveMesh.H"
30 #include "processorLduInterface.H"
31 #include "globalIndex.H"
32 
33 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
34 
35 
36 Foam::fvMeshPrimitiveLduAddressing::fvMeshPrimitiveLduAddressing
37 (
38  const fvMesh& mesh
39 )
40 :
41  lduAddressing(mesh.nCells()),
42  lowerAddr_
43  (
45  (
46  mesh.faceOwner(),
47  mesh.nInternalFaces()
48  )
49  ),
50  upperAddr_(mesh.faceNeighbour()),
51  patchAddr_(mesh.boundary().size()),
52  patchSchedule_(mesh.globalData().patchSchedule())
53 {
54  forAll(mesh.boundary(), patchI)
55  {
56  patchAddr_[patchI] = &mesh.boundary()[patchI].faceCells();
57  }
58 }
59 
60 
61 Foam::fvMeshPrimitiveLduAddressing::fvMeshPrimitiveLduAddressing
62 (
63  const label nCells,
64  labelList&& lowerAddr,
65  labelList&& upperAddr,
66  const List<const labelUList*>& patchAddr,
67  const lduSchedule& ps
68 )
69 :
70  lduAddressing(nCells),
71  lowerAddr_(std::move(lowerAddr)),
72  upperAddr_(std::move(upperAddr)),
73  patchAddr_(patchAddr),
74  patchSchedule_(ps)
75 {}
76 
77 
78 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
79 
81 (
82  const lduAddressing& addr,
83  const label a,
84  const label b
85 )
86 {
87  label own = min(a, b);
88 
89  label nbr = max(a, b);
90 
91  label startLabel = addr.ownerStartAddr()[own];
92 
93  label endLabel = addr.ownerStartAddr()[own + 1];
94 
95  const labelUList& neighbour = addr.upperAddr();
96 
97  for (label i = startLabel; i < endLabel; i++)
98  {
99  if (neighbour[i] == nbr)
100  {
101  return i;
102  }
103  }
104  return -1;
105 }
106 
107 
109 (
110  const lduAddressing& addr,
111  const labelListList& nbrCells,
112  label& nExtraFaces,
113  labelList& newLowerAddr,
114  labelList& newUpperAddr,
115  labelListList& nbrCellFaces,
116  const globalIndex& globalNumbering,
117  const labelList& globalCellIDs,
118  labelListList& localFaceCells,
119  labelListList& remoteFaceCells
120 )
121 {
122  label nCells = addr.size();
123  label nFaces = addr.upperAddr().size();
124  labelList nProcFaces(Pstream::nProcs(), Zero);
125 
126  // Count additional faces
127  nExtraFaces = 0;
128  forAll(nbrCells, cellI)
129  {
130  const labelList& nbrs = nbrCells[cellI];
131  forAll(nbrs, nbrI)
132  {
133  if (nbrs[nbrI] < nCells)
134  {
135  // Local cell
136  if (triIndex(addr, cellI, nbrs[nbrI]) == -1)
137  {
138  nExtraFaces++;
139  }
140  }
141  else
142  {
143  label globalNbr = globalCellIDs[nbrs[nbrI]];
144  label procI = globalNumbering.whichProcID(globalNbr);
145  nProcFaces[procI]++;
146  }
147  }
148  }
149 
150  // Create space for extra addressing
151  newLowerAddr.setSize(nFaces + nExtraFaces);
152  newUpperAddr.setSize(nFaces + nExtraFaces);
153 
154  // Copy existing addressing
155  SubList<label>(newLowerAddr, nFaces) = addr.lowerAddr();
156  SubList<label>(newUpperAddr, nFaces) = addr.upperAddr();
157 
158 
159  // Per processor its local cells we want
160  localFaceCells.setSize(Pstream::nProcs());
161  remoteFaceCells.setSize(Pstream::nProcs());
162  forAll(nProcFaces, procI)
163  {
164  localFaceCells[procI].setSize(nProcFaces[procI]);
165  remoteFaceCells[procI].setSize(nProcFaces[procI]);
166  }
167  nProcFaces = 0;
168 
169  nbrCellFaces.setSize(nbrCells.size());
170  forAll(nbrCells, cellI)
171  {
172  const labelList& nbrs = nbrCells[cellI];
173  labelList& faces = nbrCellFaces[cellI];
174  faces.setSize(nbrs.size());
175 
176  forAll(nbrs, nbrI)
177  {
178  label nbrCellI = nbrs[nbrI];
179 
180  if (nbrCellI < nCells)
181  {
182  // Find neighbour cell in owner list
183  label faceI = triIndex(addr, cellI, nbrCellI);
184  if (faceI == -1)
185  {
186  faceI = nFaces++;
187  newLowerAddr[faceI] = min(cellI, nbrCellI);
188  newUpperAddr[faceI] = max(cellI, nbrCellI);
189  }
190  faces[nbrI] = faceI;
191  }
192  else
193  {
194  // Remote cell
195  faces[nbrI] = -1;
196 
197  label globalNbr = globalCellIDs[nbrCellI];
198  label procI = globalNumbering.whichProcID(globalNbr);
199  label remoteCellI = globalNumbering.toLocal(procI, globalNbr);
200 
201  label procFaceI = nProcFaces[procI]++;
202  localFaceCells[procI][procFaceI] = cellI;
203  remoteFaceCells[procI][procFaceI] = remoteCellI;
204  }
205  }
206  }
207 
208  // Reorder upper-triangular
209  labelList oldToNew
210  (
211  lduPrimitiveMesh::upperTriOrder
212  (
213  addr.size(),
214  newLowerAddr,
215  newUpperAddr
216  )
217  );
218 
219  // Shuffle face-to-cell addressing
220  inplaceReorder(oldToNew, newLowerAddr);
221  inplaceReorder(oldToNew, newUpperAddr);
222  // Update cell-to-face addressing
223  forAll(nbrCellFaces, cellI)
224  {
225  inplaceRenumber(oldToNew, nbrCellFaces[cellI]);
226  }
227 
228  //if (debug)
229  //{
230  // for
231  // (
232  // label i = addr.upperAddr().size();
233  // i < oldToNew.size();
234  // i++
235  // )
236  // {
237  // label faceI = oldToNew[i];
238  // Pout<< "new face:" << faceI << endl
239  // << " owner:" << newLowerAddr[faceI]
240  // << " neighbour:" << newUpperAddr[faceI]
241  // << endl;
242  // }
243  //
244  // forAll(nbrCellFaces, cellI)
245  // {
246  // const labelList& nbrs = nbrCells[cellI];
247  // const labelList& nbrFaces = nbrCellFaces[cellI];
248  // if (nbrs.size())
249  // {
250  // Pout<< "cell:" << cellI << " has additional neighbours:"
251  // << endl;
252  // forAll(nbrs, i)
253  // {
254  // label faceI = nbrFaces[i];
255  // Pout<< " nbr:" << nbrs[i]
256  // << " through face:" << faceI
257  // << " with own:" << newLowerAddr[faceI]
258  // << " with nei:" << newUpperAddr[faceI]
259  // << endl;
260  // }
261  // }
262  // }
263  //}
264 
265  return oldToNew;
266 }
267 
268 
269 // ************************************************************************* //
Foam::lduAddressing
The class contains the addressing required by the lduMatrix: upper, lower and losort.
Definition: lduAddressing.H:114
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
globalIndex.H
Foam::lduAddressing::ownerStartAddr
const labelUList & ownerStartAddr() const
Return owner start addressing.
Definition: lduAddressing.C:199
Foam::lduAddressing::size
label size() const
Return number of equations.
Definition: lduAddressing.H:171
Foam::lduAddressing::upperAddr
virtual const labelUList & upperAddr() const =0
Return upper addressing.
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
processorLduInterface.H
Foam::fvMeshPrimitiveLduAddressing::addAddressing
static labelList addAddressing(const lduAddressing &addr, const labelListList &nbrCells, label &nExtraFaces, labelList &lower, labelList &upper, labelListList &nbrCellFaces, const globalIndex &, const labelList &globalCellIDs, labelListList &localFaceCells, labelListList &remoteFaceCells)
Given additional addressing (in the form of additional neighbour.
Definition: fvMeshPrimitiveLduAddressing.C:109
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::ListListOps::inplaceRenumber
void inplaceRenumber(const labelUList &oldToNew, IntListType &lists)
Inplace renumber the values (not the indices) of a list of lists.
Definition: ensightOutput.H:88
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:83
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
Foam::globalIndex::toLocal
label toLocal(const label i) const
From global to local on current processor.
Definition: globalIndexI.H:229
Foam::lduAddressing::lowerAddr
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
Foam::List< label >
Foam::globalIndex::whichProcID
label whichProcID(const label i) const
Which processor does global come from? Binary search.
Definition: globalIndexI.H:235
Foam::UList< label >
Foam::UList::size
void size(const label n) noexcept
Override size to be inconsistent with allocated storage.
Definition: UListI.H:360
fvMeshPrimitiveLduAddressing.H
Foam::inplaceReorder
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
Definition: ListOpsTemplates.C:124
lduPrimitiveMesh.H
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::fvMeshPrimitiveLduAddressing::triIndex
static label triIndex(const lduAddressing &, const label, const label)
Return off-diagonal index given owner and neighbour label. Return.
Definition: fvMeshPrimitiveLduAddressing.C:81