faFieldDecomposer.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) 2016-2017 Wikki Ltd
9  Copyright (C) 2021-2024 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 "faFieldDecomposer.H"
30 
31 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
32 
34 (
35  const label sizeBeforeMapping,
36  const labelUList& addressingSlice,
37  const label addressingOffset
38 )
39 :
40  sizeBeforeMapping_(sizeBeforeMapping),
41  directAddressing_(addressingSlice)
42 {
43  forAll(directAddressing_, i)
44  {
45  // Subtract one to align addressing.
46  // directAddressing_[i] -= addressingOffset + 1;
47  // ZT, 12/Nov/2010
48  directAddressing_[i] -= addressingOffset;
49  }
50 }
51 
52 
55 (
56  const label nTotalFaces,
57  const labelUList& owner, // == mesh.edgeOwner()
58  const labelUList& neigh, // == mesh.edgeNeighbour()
59  const labelUList& addressingSlice,
60  const bitSet& flip
61 )
62 :
63  sizeBeforeMapping_(nTotalFaces),
64  directAddressing_(addressingSlice.size())
65 {
66  forAll(directAddressing_, i)
67  {
68  // Subtract one to align addressing.
69  label ai = addressingSlice[i];
70 // label ai = mag(addressingSlice[i]) - 1;
71 
72  if (ai < neigh.size())
73  {
74  // This is a regular edge. it has been an internal edge
75  // of the original mesh and now it has become a edge
76  // on the parallel boundary
77 
78  if (flip[i])
79  {
80  // We are the neighbour side so use the owner value
81  directAddressing_[i] = owner[ai];
82  }
83  else
84  {
85  // We are the owner side so use the neighbour value
86  directAddressing_[i] = neigh[ai];
87  }
88  }
89  else
90  {
91  // This is a edge that used to be on a cyclic boundary
92  // but has now become a parallel patch edge. I cannot
93  // do the interpolation properly (I would need to look
94  // up the different (edge) list of data), so I will
95  // just grab the value from the owner face
96 
97  directAddressing_[i] = owner[ai];
98  }
99  }
100 }
101 
102 
105 (
106  label sizeBeforeMapping,
107  const labelUList& addressingSlice
108 )
109 :
110  sizeBeforeMapping_(sizeBeforeMapping),
111  addressing_(addressingSlice.size()),
112  weights_(addressingSlice.size())
113 {
114  forAll(addressing_, i)
115  {
116  addressing_[i].resize(1);
117  weights_[i].resize(1);
118 
119  addressing_[i][0] = mag(addressingSlice[i]) - 1;
120  weights_[i][0] = sign(addressingSlice[i]);
121  }
122 }
123 
124 
125 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
126 
127 Foam::faFieldDecomposer::faFieldDecomposer
128 (
129  const Foam::zero,
130  const faMesh& procMesh,
131  const labelList& edgeAddressing,
132  const labelList& faceAddressing,
133  const labelList& boundaryAddressing
134 )
135 :
136  procMesh_(procMesh),
137  edgeAddressing_(edgeAddressing),
138  faceAddressing_(faceAddressing),
139  boundaryAddressing_(boundaryAddressing),
140  // Mappers
141  patchFieldDecomposerPtrs_(),
142  processorAreaPatchFieldDecomposerPtrs_(),
143  processorEdgePatchFieldDecomposerPtrs_()
144 {}
145 
146 
147 Foam::faFieldDecomposer::faFieldDecomposer
148 (
149  const faMesh& completeMesh,
150  const faMesh& procMesh,
151  const labelList& edgeAddressing,
152  const labelList& faceAddressing,
153  const labelList& boundaryAddressing
154 )
155 :
157  (
158  zero{},
159  procMesh,
160  edgeAddressing,
161  faceAddressing,
162  boundaryAddressing
163  )
164 {
165  reset(completeMesh);
166 }
167 
168 
169 Foam::faFieldDecomposer::faFieldDecomposer
170 (
171  const label nTotalFaces,
172  const List<labelRange>& boundaryRanges,
173  const labelUList& edgeOwner,
174  const labelUList& edgeNeigbour,
175 
176  const faMesh& procMesh,
177  const labelList& edgeAddressing,
178  const labelList& faceAddressing,
179  const labelList& boundaryAddressing
180 )
181 :
183  (
184  zero{},
185  procMesh,
186  edgeAddressing,
187  faceAddressing,
188  boundaryAddressing
189  )
190 {
191  reset(nTotalFaces, boundaryRanges, edgeOwner, edgeNeigbour);
192 }
193 
194 
195 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
198 {
199  return patchFieldDecomposerPtrs_.empty();
200 }
201 
202 
204 {
205  patchFieldDecomposerPtrs_.clear();
206  processorAreaPatchFieldDecomposerPtrs_.clear();
207  processorEdgePatchFieldDecomposerPtrs_.clear();
208 }
209 
210 
212 (
213  const label nTotalFaces,
214  const List<labelRange>& boundaryRanges,
215  const labelUList& edgeOwner,
216  const labelUList& edgeNeigbour
217 )
218 {
219  clear();
220  const label nMappers = procMesh_.boundary().size();
221  patchFieldDecomposerPtrs_.resize(nMappers);
222  processorAreaPatchFieldDecomposerPtrs_.resize(nMappers);
223  processorEdgePatchFieldDecomposerPtrs_.resize(nMappers);
224 
225  forAll(boundaryAddressing_, patchi)
226  {
227  const label oldPatchi = boundaryAddressing_[patchi];
228  const faPatch& fap = procMesh_.boundary()[patchi];
229  const labelSubList localPatchSlice(fap.patchSlice(edgeAddressing_));
230 
231  if (oldPatchi >= 0)
232  {
233  patchFieldDecomposerPtrs_.set
234  (
235  patchi,
236  new patchFieldDecomposer
237  (
238  boundaryRanges[oldPatchi].size(),
239  localPatchSlice,
240  boundaryRanges[oldPatchi].start()
241  )
242  );
243  }
244  else
245  {
246  // No oldPatch - is processor patch. edgeAddressing_ does
247  // not have 'flip' sign so use the face map to see which side
248  // we've got.
249  bitSet flipMap(localPatchSlice.size());
250  forAll(flipMap, i)
251  {
252  const label ownFacei = faceAddressing_[fap.edgeFaces()[i]];
253  flipMap[i] = (edgeOwner[localPatchSlice[i]] != ownFacei);
254  }
255 
256  processorAreaPatchFieldDecomposerPtrs_.set
257  (
258  patchi,
259  new processorAreaPatchFieldDecomposer
260  (
261  nTotalFaces,
262  edgeOwner,
263  edgeNeigbour,
264  localPatchSlice,
265  flipMap
266  )
267  );
268 
269  processorEdgePatchFieldDecomposerPtrs_.set
270  (
271  patchi,
272  new processorEdgePatchFieldDecomposer
273  (
274  procMesh_.boundary()[patchi].size(),
275  localPatchSlice
276  )
277  );
278  }
279  }
280 }
281 
282 
283 void Foam::faFieldDecomposer::reset(const faMesh& completeMesh)
284 {
285  clear();
286  const label nMappers = procMesh_.boundary().size();
287  patchFieldDecomposerPtrs_.resize(nMappers);
288  processorAreaPatchFieldDecomposerPtrs_.resize(nMappers);
289  processorEdgePatchFieldDecomposerPtrs_.resize(nMappers);
290 
291  // Create weightings now - needed for proper parallel synchronization
293  // Disabled the above (2022-04-04)
294  // Use weights if they already exist, otherwise simply ignore
295 
296  // faPatches don't have their own start() - so these are invariant
297  const labelList completePatchStarts
298  (
299  completeMesh.boundary().patchStarts()
300  );
301 
302  forAll(boundaryAddressing_, patchi)
303  {
304  const label oldPatchi = boundaryAddressing_[patchi];
305  const faPatch& fap = procMesh_.boundary()[patchi];
306  const labelSubList localPatchSlice(fap.patchSlice(edgeAddressing_));
307 
308  if (oldPatchi >= 0)
309  {
310  patchFieldDecomposerPtrs_.set
311  (
312  patchi,
313  new patchFieldDecomposer
314  (
315  completeMesh.boundary()[oldPatchi].size(),
316  localPatchSlice,
317  completePatchStarts[oldPatchi]
318  )
319  );
320  }
321  else
322  {
323  const auto& edgeOwner = completeMesh.edgeOwner();
324  const auto& edgeNeighbour = completeMesh.edgeNeighbour();
325 
326  // No oldPatch - is processor patch. edgeAddressing_ does
327  // not have 'flip' sign so use the face map to see which side
328  // we've got.
329  bitSet flipMap(localPatchSlice.size());
330  forAll(flipMap, i)
331  {
332  const label ownFacei = faceAddressing_[fap.edgeFaces()[i]];
333  flipMap[i] = (edgeOwner[localPatchSlice[i]] != ownFacei);
334  }
335 
336  processorAreaPatchFieldDecomposerPtrs_.set
337  (
338  patchi,
339  new processorAreaPatchFieldDecomposer
340  (
341  completeMesh.nFaces(),
342  edgeOwner,
343  edgeNeighbour,
344  localPatchSlice,
345  flipMap
346  )
347  );
348 
349  processorEdgePatchFieldDecomposerPtrs_.set
350  (
351  patchi,
352  new processorEdgePatchFieldDecomposer
353  (
354  procMesh_.boundary()[patchi].size(),
355  localPatchSlice
356  )
357  );
358  }
359  }
360 }
361 
362 
363 // ************************************************************************* //
SubList< label > labelSubList
A SubList of labels.
Definition: SubList.H:55
Finite area mesh (used for 2-D non-Euclidian finite area method) defined using a patch of faces on a ...
Definition: faMesh.H:133
dimensionedScalar sign(const dimensionedScalar &ds)
const List< T >::subList patchSlice(const List< T > &values) const
This patch slice from the complete list of values, which has size mesh::nEdges(), using the virtual p...
Definition: faPatch.H:410
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
Finite Area area and edge field decomposer.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:153
processorEdgePatchFieldDecomposer(label sizeBeforeMapping, const labelUList &addressingSlice)
Construct given addressing.
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
processorAreaPatchFieldDecomposer(const label nTotalFaces, const labelUList &edgeOwner, const labelUList &edgeNeigbour, const labelUList &addressingSlice, const bitSet &flip)
Construct addressing from details.
A List obtained as a section of another List.
Definition: SubList.H:50
void reset(const faMesh &completeMesh)
Reset mappers using information from the complete mesh.
patchFieldDecomposer(const label sizeBeforeMapping, const labelUList &addressingSlice, const label addressingOffset)
Construct given addressing.
const labelUList & edgeFaces() const
Return edge-face addressing.
Definition: faPatch.C:424
Finite area patch class. Used for 2-D non-Euclidian finite area method.
Definition: faPatch.H:72
void clear()
Remove all mappers.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:59
surface1 clear()
bool empty() const
True if no mappers have been allocated.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
List< label > labelList
A List of labels.
Definition: List.H:62