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-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 "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 scalarField& weights
61 )
62 :
63  sizeBeforeMapping_(nTotalFaces),
64  addressing_(addressingSlice.size()),
65  weights_(addressingSlice.size())
66 {
67  forAll(addressing_, i)
68  {
69  // Subtract one to align addressing.
70  label ai = addressingSlice[i];
71 // label ai = mag(addressingSlice[i]) - 1;
72 
73  if (ai < neigh.size())
74  {
75  // This is a regular edge. it has been an internal edge
76  // of the original mesh and now it has become a edge
77  // on the parallel boundary
78  addressing_[i].resize(2);
79  weights_[i].resize(2);
80 
81  addressing_[i][0] = owner[ai];
82  addressing_[i][1] = neigh[ai];
83 
84  if (ai < weights.size())
85  {
86  // Edge weights exist/are usable
87  weights_[i][0] = weights[ai];
88  weights_[i][1] = 1.0 - weights[ai];
89  }
90  else
91  {
92  // No edge weights. use equal weighting
93  weights_[i][0] = 0.5;
94  weights_[i][1] = 0.5;
95  }
96  }
97  else
98  {
99  // This is a edge that used to be on a cyclic boundary
100  // but has now become a parallel patch edge. I cannot
101  // do the interpolation properly (I would need to look
102  // up the different (edge) list of data), so I will
103  // just grab the value from the owner face
104 
105  addressing_[i].resize(1);
106  weights_[i].resize(1);
107 
108  addressing_[i][0] = owner[ai];
109 
110  weights_[i][0] = 1.0;
111  }
112  }
113 }
114 
115 
118 (
119  const faMesh& mesh,
120  const labelUList& addressingSlice
121 )
122 :
123  processorAreaPatchFieldDecomposer
124  (
125  mesh.nFaces(),
126  mesh.edgeOwner(),
127  mesh.edgeNeighbour(),
128  addressingSlice,
129  (
130  mesh.hasWeights()
131  ? mesh.weights().primitiveField()
132  : scalarField::null()
133  )
134  )
135 {}
136 
137 
140 (
141  label sizeBeforeMapping,
142  const labelUList& addressingSlice
143 )
144 :
145  sizeBeforeMapping_(sizeBeforeMapping),
146  addressing_(addressingSlice.size()),
147  weights_(addressingSlice.size())
148 {
149  forAll(addressing_, i)
150  {
151  addressing_[i].resize(1);
152  weights_[i].resize(1);
153 
154  addressing_[i][0] = mag(addressingSlice[i]) - 1;
155  weights_[i][0] = sign(addressingSlice[i]);
156  }
157 }
158 
159 
160 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
161 
162 Foam::faFieldDecomposer::faFieldDecomposer
163 (
164  const Foam::zero,
165  const faMesh& procMesh,
166  const labelList& edgeAddressing,
167  const labelList& faceAddressing,
168  const labelList& boundaryAddressing
169 )
170 :
171  procMesh_(procMesh),
172  edgeAddressing_(edgeAddressing),
173  faceAddressing_(faceAddressing),
174  boundaryAddressing_(boundaryAddressing),
175  // Mappers
176  patchFieldDecomposerPtrs_(),
177  processorAreaPatchFieldDecomposerPtrs_(),
178  processorEdgePatchFieldDecomposerPtrs_()
179 {}
180 
181 
182 Foam::faFieldDecomposer::faFieldDecomposer
183 (
184  const faMesh& completeMesh,
185  const faMesh& procMesh,
186  const labelList& edgeAddressing,
187  const labelList& faceAddressing,
188  const labelList& boundaryAddressing
189 )
190 :
192  (
193  zero{},
194  procMesh,
195  edgeAddressing,
196  faceAddressing,
197  boundaryAddressing
198  )
199 {
200  reset(completeMesh);
201 }
202 
203 
204 Foam::faFieldDecomposer::faFieldDecomposer
205 (
206  const label nTotalFaces,
207  const List<labelRange>& boundaryRanges,
208  const labelUList& edgeOwner,
209  const labelUList& edgeNeigbour,
210 
211  const faMesh& procMesh,
212  const labelList& edgeAddressing,
213  const labelList& faceAddressing,
214  const labelList& boundaryAddressing
215 )
216 :
218  (
219  zero{},
220  procMesh,
221  edgeAddressing,
222  faceAddressing,
223  boundaryAddressing
224  )
225 {
226  reset(nTotalFaces, boundaryRanges, edgeOwner, edgeNeigbour);
227 }
228 
229 
230 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
233 {
234  return patchFieldDecomposerPtrs_.empty();
235 }
236 
237 
239 {
240  patchFieldDecomposerPtrs_.clear();
241  processorAreaPatchFieldDecomposerPtrs_.clear();
242  processorEdgePatchFieldDecomposerPtrs_.clear();
243 }
244 
245 
247 (
248  const label nTotalFaces,
249  const List<labelRange>& boundaryRanges,
250  const labelUList& edgeOwner,
251  const labelUList& edgeNeigbour
252 )
253 {
254  clear();
255  const label nMappers = procMesh_.boundary().size();
256 
257  patchFieldDecomposerPtrs_.resize(nMappers);
258  processorAreaPatchFieldDecomposerPtrs_.resize(nMappers);
259  processorEdgePatchFieldDecomposerPtrs_.resize(nMappers);
260 
261  forAll(boundaryAddressing_, patchi)
262  {
263  const label oldPatchi = boundaryAddressing_[patchi];
264  const faPatch& fap = procMesh_.boundary()[patchi];
265  const labelSubList localPatchSlice(fap.patchSlice(edgeAddressing_));
266 
267  if (oldPatchi >= 0)
268  {
269  patchFieldDecomposerPtrs_.set
270  (
271  patchi,
272  new patchFieldDecomposer
273  (
274  boundaryRanges[oldPatchi].size(),
275  localPatchSlice,
276  boundaryRanges[oldPatchi].start()
277  )
278  );
279  }
280  else
281  {
282  processorAreaPatchFieldDecomposerPtrs_.set
283  (
284  patchi,
285  new processorAreaPatchFieldDecomposer
286  (
287  nTotalFaces,
288  edgeOwner,
289  edgeNeigbour,
290  localPatchSlice
291  )
292  );
293 
294  processorEdgePatchFieldDecomposerPtrs_.set
295  (
296  patchi,
297  new processorEdgePatchFieldDecomposer
298  (
299  procMesh_.boundary()[patchi].size(),
300  localPatchSlice
301  )
302  );
303  }
304  }
305 }
306 
307 
308 void Foam::faFieldDecomposer::reset(const faMesh& completeMesh)
309 {
310  clear();
311  const label nMappers = procMesh_.boundary().size();
312  patchFieldDecomposerPtrs_.resize(nMappers);
313  processorAreaPatchFieldDecomposerPtrs_.resize(nMappers);
314  processorEdgePatchFieldDecomposerPtrs_.resize(nMappers);
315 
316  // Create weightings now - needed for proper parallel synchronization
318  // Disabled the above (2022-04-04)
319  // Use weights if they already exist, otherwise simply ignore
320 
321  // faPatches don't have their own start() - so these are invariant
322  const labelList completePatchStarts
323  (
324  completeMesh.boundary().patchStarts()
325  );
326 
327  forAll(boundaryAddressing_, patchi)
328  {
329  const label oldPatchi = boundaryAddressing_[patchi];
330  const faPatch& fap = procMesh_.boundary()[patchi];
331  const labelSubList localPatchSlice(fap.patchSlice(edgeAddressing_));
332 
333  if (oldPatchi >= 0)
334  {
335  patchFieldDecomposerPtrs_.set
336  (
337  patchi,
338  new patchFieldDecomposer
339  (
340  completeMesh.boundary()[oldPatchi].size(),
341  localPatchSlice,
342  completePatchStarts[oldPatchi]
343  )
344  );
345  }
346  else
347  {
348  processorAreaPatchFieldDecomposerPtrs_.set
349  (
350  patchi,
351  new processorAreaPatchFieldDecomposer
352  (
353  completeMesh,
354  localPatchSlice
355  )
356  );
357 
358  processorEdgePatchFieldDecomposerPtrs_.set
359  (
360  patchi,
361  new processorEdgePatchFieldDecomposer
362  (
363  procMesh_.boundary()[patchi].size(),
364  localPatchSlice
365  )
366  );
367  }
368  }
369 }
370 
371 
372 // ************************************************************************* //
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:87
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:160
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
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.
dynamicFvMesh & mesh
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
patchFieldDecomposer(const label sizeBeforeMapping, const labelUList &addressingSlice, const label addressingOffset)
Construct given addressing.
patchWriters clear()
const scalarListList & weights() const
Return the interpolation weights.
Finite area patch class. Used for 2-D non-Euclidian finite area method.
Definition: faPatch.H:72
void clear()
Remove all mappers.
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
processorAreaPatchFieldDecomposer(const label nTotalFaces, const labelUList &edgeOwner, const labelUList &edgeNeigbour, const labelUList &addressingSlice, const scalarField &edgeWeights=scalarField::null())
Construct addressing from details.