Loading...
Searching...
No Matches
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
35Foam::fvMeshPrimitiveLduAddressing::fvMeshPrimitiveLduAddressing
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
55Foam::fvMeshPrimitiveLduAddressing::fvMeshPrimitiveLduAddressing
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(label n)
Alias for resize().
Definition List.H:536
A non-owning sub-view of a List (allocated or unallocated storage).
Definition SubList.H:61
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
Definition UPstream.H:1697
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition UPtrList.H:101
Smooth ATC in cells next to a set of patches supplied by type.
Definition faceCells.H:55
virtual const labelUList & patchAddr(const label patchi) const
Return patch addressing for given patch.
static label triIndex(const lduAddressing &, const label, const label)
Return off-diagonal index given owner and neighbour label.
virtual const labelUList & lowerAddr() const noexcept
Return lower addressing (i.e. lower label = upper triangle).
virtual const lduSchedule & patchSchedule() const noexcept
Return patch field evaluation schedule.
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 cells, i.e. like cellCells).
virtual const labelUList & upperAddr() const noexcept
Return upper addressing (i.e. upper label).
Mesh data needed to do the Finite Volume discretisation.
Definition fvMesh.H:85
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
Definition globalIndex.H:77
label toLocal(const label proci, const label i) const
From global to local on proci.
label whichProcID(const label proci, const label i) const
Which processor does global id come from? Checks proci first (assumed to occur reasonably frequently)...
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.
lduAddressing(const lduAddressing &)=delete
No copy construct.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
label size() const noexcept
Return number of equations.
static labelList upperTriOrder(const label nCells, const labelUList &lower, const labelUList &upper)
Calculate upper-triangular order.
faceListList boundary
dynamicFvMesh & mesh
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:40
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values within a list.
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
List< label > labelList
A List of labels.
Definition List.H:62
List< lduScheduleEntry > lduSchedule
A List of lduSchedule entries.
Definition lduSchedule.H:46
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:26
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
UList< label > labelUList
A UList of labels.
Definition UList.H:75
volScalarField & b
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299