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  }
138  return stencilWithValues;
139 }
140 
141 
142 template<typename Type>
144 (
145  const boolList& zone,
146  const VolumeField<Type>& phi
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;
161 
162  if (UPstream::parRun())
163  {
164  if (sendConnections_.empty())
165  {
167  << "The send/recv connections not initialized - "
168  << "likely that setUpCommforZone() was not called"
169  << endl;
170  // But don't exit/abort for now
171  }
172 
173  // Stream the send data into PstreamBuffers,
174  // which we also use to track the current topology.
175 
176  pBufs_.clear();
177 
178  for (const int proci : pBufs_.allProcs())
179  {
180  const auto& indices = send_[proci];
181 
182  if (proci != UPstream::myProcNo() && !indices.empty())
183  {
184  // Serialize as Map
185  Map<Type> sendValues(2*indices.size());
186 
187  for (const label sendIdx : indices)
188  {
189  sendValues.insert
190  (
191  sendIdx,
192  getLocalValue(phi, globalNumbering_.toLocal(sendIdx))
193  );
194  }
195 
196  UOPstream toProc(proci, pBufs_);
197  toProc << sendValues;
198  }
199  }
200 
201  pBufs_.finishedSends(sendConnections_, sendProcs_, recvProcs_);
202 
203  for (const int proci : pBufs_.allProcs())
204  {
205  if (proci != UPstream::myProcNo() && pBufs_.recvDataCount(proci))
206  {
207  UIPstream fromProc(proci, pBufs_);
208  Map<Type> tmpValues(fromProc);
209 
210  neiValues += tmpValues;
211  }
212  }
213  }
214 
215  return neiValues;
216 }
217 
218 
219 // ************************************************************************* //
const polyBoundaryMesh & pbm
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
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:598
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:531
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1049
Generic GeometricField class.
Definition: areaFieldsFwd.H:50
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
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.
List< bool > boolList
A List of bools.
Definition: List.H:60
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.