FreeFOAM The Cross-Platform CFD Toolkit
fvPatchMapper.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 | Copyright (C) 1991-2010 OpenCFD Ltd.
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 "fvPatchMapper.H"
27 #include <finiteVolume/fvPatch.H>
29 #include <finiteVolume/fvMesh.H>
30 #include <OpenFOAM/mapPolyMesh.H>
31 #include <OpenFOAM/faceMapper.H>
32 
33 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 
35 void Foam::fvPatchMapper::calcAddressing() const
36 {
37  if
38  (
39  directAddrPtr_
40  || interpolationAddrPtr_
41  || weightsPtr_
42  )
43  {
45  (
46  "void fvPatchMapper::calcAddressing() const)"
47  ) << "Addressing already calculated"
48  << abort(FatalError);
49  }
50 
51  // Mapping
52  const label oldPatchStart =
53  faceMap_.oldPatchStarts()[patch_.index()];
54 
55  const label oldPatchEnd =
56  oldPatchStart + faceMap_.oldPatchSizes()[patch_.index()];
57 
58  // Assemble the maps: slice to patch
59  if (direct())
60  {
61  // Direct mapping - slice to size
62  directAddrPtr_ = new labelList
63  (
64  patch_.patchSlice
65  (
66  static_cast<const labelList&>(faceMap_.directAddressing())
67  )
68  );
69  labelList& addr = *directAddrPtr_;
70 
71  // Adjust mapping to manage hits into other patches and into
72  // internal
73  forAll (addr, faceI)
74  {
75  if
76  (
77  addr[faceI] >= oldPatchStart
78  && addr[faceI] < oldPatchEnd
79  )
80  {
81  addr[faceI] -= oldPatchStart;
82  }
83  else
84  {
85  addr[faceI] = 0;
86  }
87  }
88 
89  if (fvMesh::debug)
90  {
91  if (min(addr) < 0)
92  {
94  (
95  "void fvPatchMapper::calcAddressing() const"
96  ) << "Error in patch mapping for patch "
97  << patch_.index() << " named " << patch_.name()
98  << abort(FatalError);
99  }
100  }
101  }
102  else
103  {
104  // Interpolative mapping
105  interpolationAddrPtr_ =
106  new labelListList
107  (
108  patch_.patchSlice(faceMap_.addressing())
109  );
110  labelListList& addr = *interpolationAddrPtr_;
111 
112  weightsPtr_ =
113  new scalarListList
114  (
115  patch_.patchSlice(faceMap_.weights())
116  );
117  scalarListList& w = *weightsPtr_;
118 
119  // Adjust mapping to manage hits into other patches and into
120  // internal
121  forAll (addr, faceI)
122  {
123  labelList& curAddr = addr[faceI];
124  scalarList& curW = w[faceI];
125 
126  if
127  (
128  min(curAddr) >= oldPatchStart
129  && max(curAddr) < oldPatchEnd
130  )
131  {
132  // No adjustment of weights, just subtract patch start
133  forAll (curAddr, i)
134  {
135  curAddr[i] -= oldPatchStart;
136  }
137  }
138  else
139  {
140  // Need to recalculate weights to exclude hits into internal
141  labelList newAddr(curAddr.size(), false);
142  scalarField newWeights(curAddr.size());
143  label nActive = 0;
144 
145  forAll (curAddr, lfI)
146  {
147  if
148  (
149  curAddr[lfI] >= oldPatchStart
150  && curAddr[lfI] < oldPatchEnd
151  )
152  {
153  newAddr[nActive] = curAddr[lfI] - oldPatchStart;
154  newWeights[nActive] = curW[lfI];
155  nActive++;
156  }
157  }
158 
159  // Cater for bad mapping
160  if (nActive == 0)
161  {
162  newAddr[nActive] = 0;
163  newWeights[nActive] = 1;
164  nActive++;
165  }
166 
167  newAddr.setSize(nActive);
168  newWeights.setSize(nActive);
169 
170  // Re-scale the weights
171  newWeights /= sum(newWeights);
172 
173  // Reset addressing and weights
174  curAddr = newAddr;
175  curW = newWeights;
176  }
177  }
178 
179  if (fvMesh::debug)
180  {
181  forAll (addr, i)
182  {
183  if (min(addr[i]) < 0)
184  {
186  (
187  "void fvPatchMapper::calcAddressing() const"
188  ) << "Error in patch mapping for patch "
189  << patch_.index() << " named " << patch_.name()
190  << abort(FatalError);
191  }
192  }
193  }
194  }
195 }
196 
197 
198 void Foam::fvPatchMapper::clearOut()
199 {
200  deleteDemandDrivenData(directAddrPtr_);
201  deleteDemandDrivenData(interpolationAddrPtr_);
202  deleteDemandDrivenData(weightsPtr_);
203 }
204 
205 
206 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
207 
208 // Construct from components
209 Foam::fvPatchMapper::fvPatchMapper
210 (
211  const fvPatch& patch,
212  const faceMapper& faceMap
213 )
214 :
215  patch_(patch),
216  faceMap_(faceMap),
217  sizeBeforeMapping_(faceMap.oldPatchSizes()[patch_.index()]),
218  directAddrPtr_(NULL),
219  interpolationAddrPtr_(NULL),
220  weightsPtr_(NULL)
221 {}
222 
223 
224 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
225 
227 {
228  clearOut();
229 }
230 
231 
232 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
233 
235 {
236  if (!direct())
237  {
239  (
240  "const unallocLabelList& fvPatchMapper::directAddressing() const"
241  ) << "Requested direct addressing for an interpolative mapper."
242  << abort(FatalError);
243  }
244 
245  if (!directAddrPtr_)
246  {
247  calcAddressing();
248  }
249 
250  return *directAddrPtr_;
251 }
252 
253 
255 {
256  if (direct())
257  {
259  (
260  "const labelListList& fvPatchMapper::addressing() const"
261  ) << "Requested interpolative addressing for a direct mapper."
262  << abort(FatalError);
263  }
264 
265  if (!interpolationAddrPtr_)
266  {
267  calcAddressing();
268  }
269 
270  return *interpolationAddrPtr_;
271 }
272 
273 
275 {
276  if (direct())
277  {
279  (
280  "const scalarListList& fvPatchMapper::weights() const"
281  ) << "Requested interpolative weights for a direct mapper."
282  << abort(FatalError);
283  }
284 
285  if (!weightsPtr_)
286  {
287  calcAddressing();
288  }
289 
290  return *weightsPtr_;
291 }
292 
293 
294 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
295 
296 
297 // * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
298 
299 
300 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
301 
302 
303 // ************************ vim: set sw=4 sts=4 et: ************************ //