GAMGAgglomerationTemplates.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "GAMGAgglomeration.H"
27 #include "distributionMap.H"
28 #include "globalIndex.H"
29 
30 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
31 
32 template<class Type>
34 (
35  const label comm,
36  const labelList& procIDs,
37  const Type& myVal,
38  List<Type>& allVals,
39  const int tag
40 )
41 {
42  if (Pstream::myProcNo(comm) == procIDs[0])
43  {
44  allVals.setSize(procIDs.size());
45 
46  allVals[0] = myVal;
47  for (label i=1; i<procIDs.size(); i++)
48  {
49  IPstream fromSlave
50  (
52  procIDs[i],
53  0,
54  tag,
55  comm
56  );
57 
58  fromSlave >> allVals[i];
59  }
60  }
61  else
62  {
63  OPstream toMaster
64  (
66  procIDs[0],
67  0,
68  tag,
69  comm
70  );
71  toMaster << myVal;
72  }
73 }
74 
75 
76 template<class Type>
78 (
79  Field<Type>& cf,
80  const Field<Type>& ff,
81  const labelList& fineToCoarse
82 ) const
83 {
84  cf = Zero;
85 
86  forAll(ff, i)
87  {
88  cf[fineToCoarse[i]] += ff[i];
89  }
90 }
91 
92 
93 template<class Type>
95 (
96  Field<Type>& cf,
97  const Field<Type>& ff,
98  const label fineLevelIndex,
99  const bool procAgglom
100 ) const
101 {
102  const labelList& fineToCoarse = restrictAddressing_[fineLevelIndex];
103 
104  if (!procAgglom && ff.size() != fineToCoarse.size())
105  {
107  << "field does not correspond to level " << fineLevelIndex
108  << " sizes: field = " << ff.size()
109  << " level = " << fineToCoarse.size()
110  << abort(FatalError);
111  }
112 
113  restrictField(cf, ff, fineToCoarse);
114 
115  label coarseLevelIndex = fineLevelIndex+1;
116 
117  if (procAgglom && hasProcMesh(coarseLevelIndex))
118  {
119  label fineComm = UPstream::parent(procCommunicator_[coarseLevelIndex]);
120 
121  const List<label>& procIDs = agglomProcIDs(coarseLevelIndex);
122  const labelList& offsets = cellOffsets(coarseLevelIndex);
123 
125  (
126  offsets,
127  fineComm,
128  procIDs,
129  cf,
131  Pstream::commsTypes::nonBlocking // Pstream::commsTypes::scheduled
132  );
133  }
134 }
135 
136 
137 template<class Type>
139 (
140  Field<Type>& cf,
141  const Field<Type>& ff,
142  const label fineLevelIndex
143 ) const
144 {
145  const labelList& fineToCoarse = faceRestrictAddressing_[fineLevelIndex];
146 
147  if (ff.size() != fineToCoarse.size())
148  {
150  << "field does not correspond to level " << fineLevelIndex
151  << " sizes: field = " << ff.size()
152  << " level = " << fineToCoarse.size()
153  << abort(FatalError);
154  }
155 
156  cf = Zero;
157 
158  forAll(fineToCoarse, ffacei)
159  {
160  label cFace = fineToCoarse[ffacei];
161 
162  if (cFace >= 0)
163  {
164  cf[cFace] += ff[ffacei];
165  }
166  }
167 }
168 
169 
170 template<class Type>
172 (
173  Field<Type>& ff,
174  const Field<Type>& cf,
175  const label levelIndex,
176  const bool procAgglom
177 ) const
178 {
179  const labelList& fineToCoarse = restrictAddressing_[levelIndex];
180 
181  label coarseLevelIndex = levelIndex+1;
182 
183  if (procAgglom && hasProcMesh(coarseLevelIndex))
184  {
185  label coarseComm = UPstream::parent
186  (
187  procCommunicator_[coarseLevelIndex]
188  );
189 
190  const List<label>& procIDs = agglomProcIDs(coarseLevelIndex);
191  const labelList& offsets = cellOffsets(coarseLevelIndex);
192 
193  label localSize = nCells_[levelIndex];
194 
195  Field<Type> allCf(localSize);
197  (
198  offsets,
199  coarseComm,
200  procIDs,
201  cf,
202  allCf,
204  Pstream::commsTypes::nonBlocking // Pstream::commsTypes::scheduled
205  );
206 
207  forAll(fineToCoarse, i)
208  {
209  ff[i] = allCf[fineToCoarse[i]];
210  }
211  }
212  else
213  {
214  forAll(fineToCoarse, i)
215  {
216  ff[i] = cf[fineToCoarse[i]];
217  }
218  }
219 }
220 
221 
222 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Pre-declare SubField and related Field type.
Definition: Field.H:83
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.
static void gatherList(const label comm, const labelList &procIDs, const Type &myVal, List< Type > &allVals, const int tag=Pstream::msgType())
Gather value from all procIDs onto procIDs[0].
void restrictFaceField(Field< Type > &cf, const Field< Type > &ff, const label fineLevelIndex) const
Restrict (integrate by summation) face field.
Input inter-processor communications stream.
Definition: IPstream.H:54
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
Output inter-processor communications stream.
Definition: OPstream.H:54
static label parent(const label communicator)
Definition: UPstream.H:434
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:476
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
static void gather(const labelUList &offsets, const label comm, const labelList &procIDs, const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), const Pstream::commsTypes commsType=Pstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
static void scatter(const labelUList &offsets, const label comm, const labelList &procIDs, const UList< Type > &allFld, UList< Type > &fld, const int tag=UPstream::msgType(), const Pstream::commsTypes commsType=Pstream::commsTypes::nonBlocking)
Distribute data in processor order. Requires fld to be sized!
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
const FieldField< fvPatchField, Type > & ff(const FieldField< fvPatchField, Type > &bf)
static const zero Zero
Definition: zero.H:97
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
errorManip< error > abort(error &err)
Definition: errorManip.H:131
error FatalError