Loading...
Searching...
No Matches
GAMGAgglomerationTemplates.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) 2011-2017 OpenFOAM Foundation
9 Copyright (C) 2023-2025 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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
30#include "mapDistribute.H"
31#include "globalIndex.H"
32
33// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34
35template<class Type>
37(
38 Field<Type>& cf,
39 const Field<Type>& ff,
40 const labelList& fineToCoarse
41) const
42{
43 cf = Zero;
44
45 forAll(ff, i)
46 {
47 cf[fineToCoarse[i]] += ff[i];
48 }
49}
50
51
52template<class Type>
54(
55 Field<Type>& cf,
56 const Field<Type>& ff,
57 const label fineLevelIndex,
58 const bool procAgglom
59) const
60{
61 const labelList& fineToCoarse = restrictAddressing_[fineLevelIndex];
62
63 if (!procAgglom && ff.size() != fineToCoarse.size())
64 {
66 << "field does not correspond to level " << fineLevelIndex
67 << " sizes: field = " << ff.size()
68 << " level = " << fineToCoarse.size()
69 << abort(FatalError);
70 }
71
72 // By processor agglomeration the cf might be left zero size. Make sure
73 // it is large enough.
74 cf.resize_nocopy(nCells_[fineLevelIndex]);
75 restrictField(cf, ff, fineToCoarse);
76
77 const label coarseLevelIndex = fineLevelIndex+1;
78
79 if (procAgglom && hasProcMesh(coarseLevelIndex))
80 {
81 const label coarseComm =
82 UPstream::parent(procCommunicator_[coarseLevelIndex]);
83
84 const auto& procIDs = agglomProcIDs(coarseLevelIndex);
85 const auto& offsets = cellOffsets(coarseLevelIndex);
86
88 (
89 offsets,
90 coarseComm,
91 procIDs,
92 cf,
95 );
96 }
97}
98
99
100template<class Type>
102(
103 Field<Type>& cf,
104 const Field<Type>& ff,
105 const label fineLevelIndex
106) const
107{
108 const labelList& fineToCoarse = faceRestrictAddressing_[fineLevelIndex];
109
110 if (ff.size() != fineToCoarse.size())
111 {
113 << "field does not correspond to level " << fineLevelIndex
114 << " sizes: field = " << ff.size()
115 << " level = " << fineToCoarse.size()
116 << abort(FatalError);
117 }
118
119 cf = Zero;
120
121 forAll(fineToCoarse, ffacei)
122 {
123 label cFace = fineToCoarse[ffacei];
124
125 if (cFace >= 0)
126 {
127 cf[cFace] += ff[ffacei];
128 }
129 }
130}
131
132
133template<class Type>
135(
136 Field<Type>& ff,
137 const Field<Type>& cf,
138 const label levelIndex,
139 const bool procAgglom
140) const
141{
142 const labelList& fineToCoarse = restrictAddressing_[levelIndex];
143
144 const label coarseLevelIndex = levelIndex+1;
145
146 if (procAgglom && hasProcMesh(coarseLevelIndex))
147 {
148 const label coarseComm =
149 UPstream::parent(procCommunicator_[coarseLevelIndex]);
150
151 const auto& procIDs = agglomProcIDs(coarseLevelIndex);
152 const auto& offsets = cellOffsets(coarseLevelIndex);
153
154 const label localSize = nCells_[levelIndex];
155
156 Field<Type> allCf(localSize);
158 (
159 offsets,
160 coarseComm,
161 procIDs,
162 cf,
163 allCf,
166 );
167
168 forAll(fineToCoarse, i)
169 {
170 ff[i] = allCf[fineToCoarse[i]];
171 }
172 }
173 else
174 {
175 forAll(fineToCoarse, i)
176 {
177 ff[i] = cf[fineToCoarse[i]];
178 }
179 }
180}
181
182
183template<class Type>
184const Foam::Field<Type>& Foam::GAMGAgglomeration::prolongField
185(
186 Field<Type>& ff,
187 Field<Type>& allCf, // work storage
188 const Field<Type>& cf,
189 const label levelIndex
190) const
191{
192 const labelList& fineToCoarse = restrictAddressing_[levelIndex];
193
194 const label coarseLevelIndex = levelIndex+1;
195
196 if (hasProcMesh(coarseLevelIndex))
197 {
198 const label coarseComm =
199 UPstream::parent(procCommunicator_[coarseLevelIndex]);
200
201 const auto& procIDs = agglomProcIDs(coarseLevelIndex);
202 const auto& offsets = cellOffsets(coarseLevelIndex);
203
204 const label localSize = nCells_[levelIndex];
205 allCf.resize_nocopy(localSize);
206
208 (
209 offsets,
210 coarseComm,
211 procIDs,
212 cf,
213 allCf,
216 );
217
218 forAll(fineToCoarse, i)
219 {
220 ff[i] = allCf[fineToCoarse[i]];
221 }
222 return allCf;
223 }
224 else
225 {
226 forAll(fineToCoarse, i)
227 {
228 ff[i] = cf[fineToCoarse[i]];
229 }
230 return cf;
231 }
232}
233
234
235// ************************************************************************* //
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
void restrictField(Field< Type > &cf, const Field< Type > &ff, const label fineLevelIndex, const bool procAgglom) const
Restrict (integrate by summation) cell field.
void prolongField(Field< Type > &ff, const Field< Type > &cf, const label coarseLevelIndex, const bool procAgglom) const
Prolong (interpolate by injection) cell field.
const labelList & cellOffsets(const label fineLeveli) const
Mapping from processor to procMesh cells.
labelList nCells_
The number of cells in each level.
bool hasProcMesh(const label fineLeveli) const
Check that level has combined mesh.
labelList procCommunicator_
Communicator for given level.
void restrictFaceField(Field< Type > &cf, const Field< Type > &ff, const label fineLevelIndex) const
Restrict (integrate by summation) face field.
const labelList & agglomProcIDs(const label fineLeveli) const
Set of processors to agglomerate. Element 0 is the master processor. (local, same only on those proce...
PtrList< labelField > restrictAddressing_
Cell restriction addressing array.
PtrList< labelList > faceRestrictAddressing_
Face restriction addressing array.
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition ListI.H:171
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
static label parent(int communicator)
The parent communicator.
Definition UPstream.H:1759
@ nonBlocking
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
Definition UPstream.H:84
static int & msgType() noexcept
Message tag of standard messages.
Definition UPstream.H:1926
static void scatter(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &allFld, UList< Type > &fld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking)
Distribute data in processor order.
static void gatherInplace(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, List< Type > &fld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking)
Inplace collect in processor order on master (== procIDs[0]).
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
const FieldField< fvPatchField, Type > & ff(const FieldField< fvPatchField, Type > &bf)
List< label > labelList
A List of labels.
Definition List.H:62
errorManip< error > abort(error &err)
Definition errorManip.H:139
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299