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 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  restrictField(cf, ff, fineToCoarse);
73 
74  const label coarseLevelIndex = fineLevelIndex+1;
75 
76  if (procAgglom && hasProcMesh(coarseLevelIndex))
77  {
78  const label coarseComm =
79  UPstream::parent(procCommunicator_[coarseLevelIndex]);
80 
81  const List<label>& procIDs = agglomProcIDs(coarseLevelIndex);
82  const labelList& offsets = cellOffsets(coarseLevelIndex);
83 
85  (
86  offsets,
87  coarseComm,
88  procIDs,
89  cf,
91  Pstream::commsTypes::nonBlocking //Pstream::commsTypes::scheduled
92  );
93  }
94 }
95 
96 
97 template<class Type>
99 (
100  Field<Type>& cf,
101  const Field<Type>& ff,
102  const label fineLevelIndex
103 ) const
104 {
105  const labelList& fineToCoarse = faceRestrictAddressing_[fineLevelIndex];
106 
107  if (ff.size() != fineToCoarse.size())
108  {
110  << "field does not correspond to level " << fineLevelIndex
111  << " sizes: field = " << ff.size()
112  << " level = " << fineToCoarse.size()
113  << abort(FatalError);
114  }
115 
116  cf = Zero;
117 
118  forAll(fineToCoarse, ffacei)
119  {
120  label cFace = fineToCoarse[ffacei];
121 
122  if (cFace >= 0)
123  {
124  cf[cFace] += ff[ffacei];
125  }
126  }
127 }
128 
129 
130 template<class Type>
132 (
133  Field<Type>& ff,
134  const Field<Type>& cf,
135  const label levelIndex,
136  const bool procAgglom
137 ) const
138 {
139  const labelList& fineToCoarse = restrictAddressing_[levelIndex];
140 
141  const label coarseLevelIndex = levelIndex+1;
142 
143  if (procAgglom && hasProcMesh(coarseLevelIndex))
144  {
145  const label coarseComm =
146  UPstream::parent(procCommunicator_[coarseLevelIndex]);
147 
148  const List<label>& procIDs = agglomProcIDs(coarseLevelIndex);
149  const labelList& offsets = cellOffsets(coarseLevelIndex);
150 
151  const label localSize = nCells_[levelIndex];
152 
153  Field<Type> allCf(localSize);
155  (
156  offsets,
157  coarseComm,
158  procIDs,
159  cf,
160  allCf,
162  Pstream::commsTypes::nonBlocking //Pstream::commsTypes::scheduled
163  );
164 
165  forAll(fineToCoarse, i)
166  {
167  ff[i] = allCf[fineToCoarse[i]];
168  }
169  }
170  else
171  {
172  forAll(fineToCoarse, i)
173  {
174  ff[i] = cf[fineToCoarse[i]];
175  }
176  }
177 }
178 
179 
180 template<class Type>
182 (
183  Field<Type>& ff,
184  Field<Type>& allCf, // work storage
185  const Field<Type>& cf,
186  const label levelIndex
187 ) const
188 {
189  const labelList& fineToCoarse = restrictAddressing_[levelIndex];
190 
191  const label coarseLevelIndex = levelIndex+1;
192 
193  if (hasProcMesh(coarseLevelIndex))
194  {
195  const label coarseComm =
196  UPstream::parent(procCommunicator_[coarseLevelIndex]);
197 
198  const List<label>& procIDs = agglomProcIDs(coarseLevelIndex);
199  const labelList& offsets = cellOffsets(coarseLevelIndex);
200 
201  const label localSize = nCells_[levelIndex];
202  allCf.resize_nocopy(localSize);
203 
205  (
206  offsets,
207  coarseComm,
208  procIDs,
209  cf,
210  allCf,
212  Pstream::commsTypes::nonBlocking //Pstream::commsTypes::scheduled
213  );
214 
215  forAll(fineToCoarse, i)
216  {
217  ff[i] = allCf[fineToCoarse[i]];
218  }
219  return allCf;
220  }
221  else
222  {
223  forAll(fineToCoarse, i)
224  {
225  ff[i] = cf[fineToCoarse[i]];
226  }
227  return cf;
228  }
229 }
230 
231 
232 // ************************************************************************* //
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:598
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:1229
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
static label parent(const label communicator)
The parent communicator.
Definition: UPstream.H:1122
Generic templated field type.
Definition: Field.H:62
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
"nonBlocking" : (MPI_Isend, MPI_Irecv)
static void gather(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
List< label > labelList
A List of labels.
Definition: List.H:62
const FieldField< fvPatchField, Type > & ff(const FieldField< fvPatchField, Type > &bf)
static void scatter(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &allFld, UList< Type > &fld, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking)
Distribute data in processor order.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127