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-2021 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
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"
31#include "globalIndex.H"
32
33// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
34
36(
37 const fvMesh& mesh
38)
39:
40 lduAddressing(mesh.nCells()),
41 lowerAddr_
42 (
43 labelList::subList
44 (
45 mesh.faceOwner(),
46 mesh.nInternalFaces()
47 )
48 ),
49 upperAddr_(mesh.faceNeighbour()),
50 patchAddr_(mesh.boundary().faceCells()),
51 patchSchedule_(mesh.globalData().patchSchedule())
52{}
53
54
56(
57 const label nCells,
58 labelList&& lowerAddr,
59 labelList&& upperAddr,
60 const UPtrList<const labelUList>& patchAddr,
61 const lduSchedule& ps
62)
63:
64 lduAddressing(nCells),
65 lowerAddr_(std::move(lowerAddr)),
66 upperAddr_(std::move(upperAddr)),
67 patchAddr_(patchAddr),
68 patchSchedule_(ps)
69{}
70
71
72// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
73
75(
76 const lduAddressing& addr,
77 const label a,
78 const label b
79)
80{
81 const label own = min(a, b);
82 const label nbr = max(a, b);
83
84 const label begLabel = addr.ownerStartAddr()[own];
85 const label endLabel = addr.ownerStartAddr()[own + 1];
86
87 const labelUList& neighbour = addr.upperAddr();
88
89 for (label i = begLabel; i < endLabel; ++i)
90 {
91 if (neighbour[i] == nbr)
92 {
93 return i;
94 }
95 }
96 return -1;
97}
98
99
101(
102 const lduAddressing& addr,
103 const labelListList& nbrCells,
104 label& nExtraFaces,
105 labelList& newLowerAddr,
106 labelList& newUpperAddr,
107 labelListList& nbrCellFaces,
108 const globalIndex& globalNumbering,
109 const labelList& globalCellIDs,
110 labelListList& localFaceCells,
111 labelListList& remoteFaceCells
112)
113{
114 label nCells = addr.size();
115 label nFaces = addr.upperAddr().size();
116 labelList nProcFaces(Pstream::nProcs(), Zero);
117
118 // Count additional faces
119 nExtraFaces = 0;
120 forAll(nbrCells, cellI)
121 {
122 const labelList& nbrs = nbrCells[cellI];
123 forAll(nbrs, nbrI)
124 {
125 if (nbrs[nbrI] < nCells)
126 {
127 // Local cell
128 if (triIndex(addr, cellI, nbrs[nbrI]) == -1)
129 {
130 nExtraFaces++;
131 }
132 }
133 else
134 {
135 label globalNbr = globalCellIDs[nbrs[nbrI]];
136 label procI = globalNumbering.whichProcID(globalNbr);
137 nProcFaces[procI]++;
138 }
139 }
140 }
141
142 // Create space for extra addressing
143 newLowerAddr.setSize(nFaces + nExtraFaces);
144 newUpperAddr.setSize(nFaces + nExtraFaces);
145
146 // Copy existing addressing
147 SubList<label>(newLowerAddr, nFaces) = addr.lowerAddr();
148 SubList<label>(newUpperAddr, nFaces) = addr.upperAddr();
149
150
151 // Per processor its local cells we want
152 localFaceCells.setSize(Pstream::nProcs());
153 remoteFaceCells.setSize(Pstream::nProcs());
154 forAll(nProcFaces, procI)
155 {
156 localFaceCells[procI].setSize(nProcFaces[procI]);
157 remoteFaceCells[procI].setSize(nProcFaces[procI]);
158 }
159 nProcFaces = 0;
160
161 nbrCellFaces.setSize(nbrCells.size());
162 forAll(nbrCells, cellI)
163 {
164 const labelList& nbrs = nbrCells[cellI];
165 labelList& faces = nbrCellFaces[cellI];
166 faces.setSize(nbrs.size());
167
168 forAll(nbrs, nbrI)
169 {
170 label nbrCellI = nbrs[nbrI];
171
172 if (nbrCellI < nCells)
173 {
174 // Find neighbour cell in owner list
175 label faceI = triIndex(addr, cellI, nbrCellI);
176 if (faceI == -1)
177 {
178 faceI = nFaces++;
179 newLowerAddr[faceI] = min(cellI, nbrCellI);
180 newUpperAddr[faceI] = max(cellI, nbrCellI);
181 }
182 faces[nbrI] = faceI;
183 }
184 else
185 {
186 // Remote cell
187 faces[nbrI] = -1;
188
189 label globalNbr = globalCellIDs[nbrCellI];
190 label procI = globalNumbering.whichProcID(globalNbr);
191 label remoteCellI = globalNumbering.toLocal(procI, globalNbr);
192
193 label procFaceI = nProcFaces[procI]++;
194 localFaceCells[procI][procFaceI] = cellI;
195 remoteFaceCells[procI][procFaceI] = remoteCellI;
196 }
197 }
198 }
199
200 // Reorder upper-triangular
201 labelList oldToNew
202 (
204 (
205 addr.size(),
206 newLowerAddr,
207 newUpperAddr
208 )
209 );
210
211 // Shuffle face-to-cell addressing
212 inplaceReorder(oldToNew, newLowerAddr);
213 inplaceReorder(oldToNew, newUpperAddr);
214 // Update cell-to-face addressing
215 forAll(nbrCellFaces, cellI)
216 {
217 inplaceRenumber(oldToNew, nbrCellFaces[cellI]);
218 }
219
220 //if (debug)
221 //{
222 // for
223 // (
224 // label i = addr.upperAddr().size();
225 // i < oldToNew.size();
226 // i++
227 // )
228 // {
229 // label faceI = oldToNew[i];
230 // Pout<< "new face:" << faceI << endl
231 // << " owner:" << newLowerAddr[faceI]
232 // << " neighbour:" << newUpperAddr[faceI]
233 // << endl;
234 // }
235 //
236 // forAll(nbrCellFaces, cellI)
237 // {
238 // const labelList& nbrs = nbrCells[cellI];
239 // const labelList& nbrFaces = nbrCellFaces[cellI];
240 // if (nbrs.size())
241 // {
242 // Pout<< "cell:" << cellI << " has additional neighbours:"
243 // << endl;
244 // forAll(nbrs, i)
245 // {
246 // label faceI = nbrFaces[i];
247 // Pout<< " nbr:" << nbrs[i]
248 // << " through face:" << faceI
249 // << " with own:" << newLowerAddr[faceI]
250 // << " with nei:" << newUpperAddr[faceI]
251 // << endl;
252 // }
253 // }
254 // }
255 //}
256
257 return oldToNew;
258}
259
260
261// ************************************************************************* //
void setSize(const label n)
Alias for resize()
Definition: List.H:218
label nProcs() const noexcept
Number of ranks associated with PstreamBuffers.
A List obtained as a section of another List.
Definition: SubList.H:70
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: UPtrList.H:71
Smooth ATC in cells next to a set of patches supplied by type.
Definition: faceCells.H:59
Variant of fvMeshLduAddressing that contains addressing instead of slices.
static label triIndex(const lduAddressing &, const label, const label)
Return off-diagonal index given owner and neighbour label.
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)
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:91
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
label toLocal(const label i) const
From global to local on current processor.
Definition: globalIndexI.H:325
The class contains the addressing required by the lduMatrix: upper, lower and losort.
const labelUList & ownerStartAddr() const
Return owner start addressing.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
label size() const
Return number of equations.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
static labelList upperTriOrder(const label nCells, const labelUList &lower, const labelUList &upper)
Calculate upper-triangular order.
faceListList boundary
dynamicFvMesh & mesh
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
volScalarField & b
Definition: createFields.H:27
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333