zoneDistributeI.H
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) 2019-2020 DLR
9  Copyright (C) 2020-2022 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 "DynamicField.H"
30 
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 
33 template<typename Type>
34 Type Foam::zoneDistribute::getLocalValue
35 (
36  const VolumeField<Type>& phi,
37  const label localIdx
38 ) const
39 {
40  if (localIdx < mesh_.nCells()) // internal: cellI
41  {
42  return phi[localIdx];
43  }
44 
45  return faceValue(phi,localIdx);
46 }
47 
48 
49 template<typename Type>
50 Type Foam::zoneDistribute::faceValue
51 (
52  const VolumeField<Type>& phi,
53  const label localIdx
54 ) const
55 {
56  const label faceI = localIdx + mesh_.nInternalFaces() - mesh_.nCells();
57 
58  const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
59 
60  // Boundary face. Find out which face of which patch
61  const label patchI = pbm.whichPatch(faceI);
62 
63  if (patchI < 0 || patchI >= pbm.size())
64  {
66  << "Cannot find patch for face " << faceI
67  << abort(FatalError);
68  }
69 
70  const polyPatch& pp = pbm[patchI];
71 
72  const label patchFaceI = pp.whichFace(faceI);
73 
74  return phi.boundaryField()[patchI][patchFaceI];
75 }
76 
77 
78 template<typename Type>
80 (
81  const VolumeField<Type>& phi,
82  const Map<Type>& valuesFromOtherProc,
83  const label gblIdx
84 ) const
85 {
86  if (globalNumbering_.isLocal(gblIdx))
87  {
88  const label localIdx = globalNumbering_.toLocal(gblIdx);
89  return getLocalValue(phi,localIdx);
90  }
91  else
92  {
93  // From other proc
94  return valuesFromOtherProc[gblIdx];
95  }
96 }
97 
98 
99 template<typename Type>
101 (
102  const boolList& zone,
103  const VolumeField<Type>& phi
104 )
105 {
106  if (zone.size() != phi.size())
107  {
109  << "size of zone: " << zone.size()
110  << "size of phi:" << phi.size()
111  << "do not match. Did the mesh change?"
112  << exit(FatalError);
113  }
114 
115 
116  // Get values from other proc
117  Map<Type> neiValues = getDatafromOtherProc(zone, phi);
118 
119  Map<Field<Type>> stencilWithValues;
120 
121  DynamicField<Type> tmpField(128);
122 
123  forAll(zone, celli)
124  {
125  if (zone[celli])
126  {
127  tmpField.clear();
128 
129  for (const label gblIdx : stencil_[celli])
130  {
131  tmpField.append(getValue(phi, neiValues, gblIdx));
132  }
133 
134  stencilWithValues.emplace(celli, tmpField);
135  }
136  }
137 
138  return stencilWithValues;
139 }
140 
141 template<typename Type>
143 (
144  const boolList& zone,
145  const VolumeField<Type>& phi,
146  const bool& checkTransformation
147 )
148 {
149  if (zone.size() != phi.size())
150  {
152  << "size of zone: " << zone.size()
153  << "size of phi:" << phi.size()
154  << "do not match. Did the mesh change?"
155  << exit(FatalError);
156  }
157 
158 
159  // Get values from other proc
160  Map<Type> neiValues = getDatafromOtherProc(zone, phi);
161 
162  Map<Field<Type>> stencilWithValues;
163 
164  DynamicField<Type> tmpField(128);
165 
166  forAll(zone, celli)
167  {
168  if (zone[celli])
169  {
170  tmpField.clear();
171 
172  for (const label gblIdx : stencil_[celli])
173  {
174  List<label> cyclicPatches(0);
175  if(checkTransformation)
176  {
177  cyclicPatches = getCyclicPatches
178  (
179  celli,
180  gblIdx,
181  getValue(phi, neiValues, gblIdx)
182  );
183  }
184 
185  tmpField.append
186  (
187  getPosition(phi, neiValues, gblIdx, cyclicPatches)
188  );
189  }
190 
191  stencilWithValues.emplace(celli, tmpField);
192  }
193  }
195  return stencilWithValues;
196 }
197 
198 
199 template<typename Type>
201 (
202  const boolList& zone,
203  const VolumeField<Type>& phi
204 )
205 {
206  if (zone.size() != phi.size())
207  {
209  << "size of zone: " << zone.size()
210  << "size of phi:" << phi.size()
211  << "do not match. Did the mesh change?"
212  << exit(FatalError);
213  }
214 
215 
216  // Get values from other proc
217  Map<Type> neiValues;
218 
219  if (UPstream::parRun())
220  {
221  if (sendConnections_.empty())
222  {
224  << "The send/recv connections not initialized - "
225  << "likely that setUpCommforZone() was not called"
226  << endl;
227  // But don't exit/abort for now
228  }
229 
230  // Stream the send data into PstreamBuffers,
231  // which we also use to track the current topology.
232 
233  pBufs_.clear();
234 
235  for (const int proci : pBufs_.allProcs())
236  {
237  const auto& indices = send_[proci];
238 
239  if (proci != UPstream::myProcNo() && !indices.empty())
240  {
241  // Serialize as Map
242  Map<Type> sendValues(2*indices.size());
243 
244  for (const label sendIdx : indices)
245  {
246  sendValues.insert
247  (
248  sendIdx,
249  getLocalValue(phi, globalNumbering_.toLocal(sendIdx))
250  );
251  }
252 
253  UOPstream toProc(proci, pBufs_);
254  toProc << sendValues;
255  }
256  }
257 
258  pBufs_.finishedSends(sendConnections_, sendProcs_, recvProcs_);
259 
260  for (const int proci : pBufs_.allProcs())
261  {
262  if (proci != UPstream::myProcNo() && pBufs_.recvDataCount(proci))
263  {
264  UIPstream fromProc(proci, pBufs_);
265  Map<Type> tmpValues(fromProc);
266 
267  neiValues += tmpValues;
268  }
269  }
270  }
271 
272  return neiValues;
273 }
274 
275 
276 // ************************************************************************* //
const polyBoundaryMesh & pbm
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Map< Type > getDatafromOtherProc(const boolList &zone, const VolumeField< Type > &phi)
Returns stencil and provides a Map with globalNumbering.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
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
Map< Field< Type > > getFields(const boolList &zone, const VolumeField< Type > &phi)
Returns stencil and provides a Map with globalNumbering.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:529
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1586
Generic GeometricField class.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
Definition: UPstream.H:1611
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:286
Base class for mesh zones.
Definition: zone.H:59
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
label whichPatch(const label meshFacei) const
Return patch index for a given mesh face index. Uses binary search.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
#define WarningInFunction
Report a warning using Foam::Warning.
label nCells() const noexcept
Number of mesh cells.
Map< Field< Type > > getPositionFields(const boolList &zone, const VolumeField< Type > &phi, const bool &checkTransformation=false)
Returns stencil and provides a Map with globalNumbering.
List< bool > boolList
A List of bools.
Definition: List.H:59
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
A HashTable to objects of type <T> with a label key.
Type getValue(const VolumeField< Type > &phi, const Map< Type > &valuesFromOtherProc, const label gblIdx) const
Gives patchNumber and patchFaceNumber for a given Geometric volume field.