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 -------------------------------------------------------------------------------
11 License
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 
29 #include "GAMGAgglomeration.H"
30 #include "mapDistribute.H"
31 #include "globalIndex.H"
32 
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 
35 template<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 
52 template<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 
100 template<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 
133 template<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 
183 template<class Type>
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 // ************************************************************************* //
void restrictField(Field< Type > &cf, const Field< Type > &ff, const label fineLevelIndex, const bool procAgglom) const
Restrict (integrate by summation) cell field.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:600
void restrictFaceField(Field< Type > &cf, const Field< Type > &ff, const label fineLevelIndex) const
Restrict (integrate by summation) face field.
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1787
static label parent(int communicator)
The parent communicator.
Definition: UPstream.H:1664
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:286
Generic templated field type.
Definition: Field.H:63
void prolongField(Field< Type > &ff, const Field< Type > &cf, const label coarseLevelIndex, const bool procAgglom) const
Prolong (interpolate by injection) cell field.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
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]).
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
List< label > labelList
A List of labels.
Definition: List.H:61
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.
const FieldField< fvPatchField, Type > & ff(const FieldField< fvPatchField, Type > &bf)
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127