FreeFOAM The Cross-Platform CFD Toolkit
processorPointPatch.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 "processorPointPatch.H"
29 #include <OpenFOAM/pointMesh.H>
31 #include <OpenFOAM/faceList.H>
34 
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 
42 defineTypeNameAndDebug(processorPointPatch, 0);
43 
45 (
46  facePointPatch,
47  processorPointPatch,
48  polyPatch
49 );
50 
51 
52 // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
53 
54 void Foam::processorPointPatch::initGeometry()
55 {
56  // Algorithm:
57  // Depending on whether the patch is a master or a slave, get the primitive
58  // patch points and filter away the points from the global patch.
59 
60  if (isMaster())
61  {
62  meshPoints_ = procPolyPatch_.meshPoints();
63  }
64  else
65  {
66  // Slave side. Create the reversed patch and pick up its points
67  // so that the order is correct
68  const polyPatch& pp = patch();
69 
70  faceList masterFaces(pp.size());
71 
72  forAll (pp, faceI)
73  {
74  masterFaces[faceI] = pp[faceI].reverseFace();
75  }
76 
77  meshPoints_ = primitiveFacePatch
78  (
79  masterFaces,
80  pp.points()
81  ).meshPoints();
82  }
83 
84  if (Pstream::parRun())
85  {
86  initPatchPatchPoints();
87  }
88 }
89 
90 
91 void Foam::processorPointPatch::calcGeometry()
92 {
93  if (Pstream::parRun())
94  {
95  calcPatchPatchPoints();
96  }
97 
98  // If it is not runing parallel or there are no global points
99  // create a 1->1 map
100  if
101  (
102  !Pstream::parRun()
103  || !boundaryMesh().mesh().globalData().nGlobalPoints()
104  )
105  {
106  nonGlobalPatchPoints_.setSize(meshPoints_.size());
107  forAll(nonGlobalPatchPoints_, i)
108  {
109  nonGlobalPatchPoints_[i] = i;
110  }
111  }
112  else
113  {
114  // Get reference to shared points
115  const labelList& sharedPoints =
116  boundaryMesh().globalPatch().meshPoints();
117 
118  nonGlobalPatchPoints_.setSize(meshPoints_.size());
119 
120  label noFiltPoints = 0;
121 
122  forAll (meshPoints_, pointI)
123  {
124  label curP = meshPoints_[pointI];
125 
126  bool found = false;
127 
128  forAll (sharedPoints, sharedI)
129  {
130  if (sharedPoints[sharedI] == curP)
131  {
132  found = true;
133  break;
134  }
135  }
136 
137  if (!found)
138  {
139  nonGlobalPatchPoints_[noFiltPoints] = pointI;
140  meshPoints_[noFiltPoints] = curP;
141  noFiltPoints++;
142  }
143  }
144 
145  nonGlobalPatchPoints_.setSize(noFiltPoints);
146  meshPoints_.setSize(noFiltPoints);
147  }
148 }
149 
150 
151 void processorPointPatch::initPatchPatchPoints()
152 {
153  if (debug)
154  {
155  Info<< "processorPointPatch::calcPatchPatchPoints() : "
156  << "constructing patch-patch points"
157  << endl;
158  }
159 
160  const polyBoundaryMesh& bm = boundaryMesh().mesh()().boundaryMesh();
161 
162  // Get the mesh points for this patch corresponding to the faces
163  const labelList& ppmp = meshPoints();
164 
165  // Create a HashSet of the point labels for this patch
166  Map<label> patchPointSet(2*ppmp.size());
167 
168  forAll (ppmp, ppi)
169  {
170  patchPointSet.insert(ppmp[ppi], ppi);
171  }
172 
173 
174  // Create the lists of patch-patch points
175  labelListList patchPatchPoints(bm.size());
176 
177  // Create the lists of patch-patch point normals
178  List<List<vector> > patchPatchPointNormals(bm.size());
179 
180  // Loop over all patches looking for other patches that share points
181  forAll(bm, patchi)
182  {
183  if
184  (
185  patchi != index() // Ignore self-self
186  && !isA<emptyPolyPatch>(bm[patchi]) // Ignore empty
187  && !bm[patchi].coupled() // Ignore other couples
188  )
189  {
190  // Get the meshPoints for the other patch
191  const labelList& meshPoints = bm[patchi].meshPoints();
192 
193  // Get the normals for the other patch
194  const vectorField& normals = bm[patchi].pointNormals();
195 
196  label pppi = 0;
197  forAll(meshPoints, pointi)
198  {
199  label ppp = meshPoints[pointi];
200 
201  // Check to see if the point of the other patch is shared with
202  // this patch
203  Map<label>::iterator iter = patchPointSet.find(ppp);
204 
205  if (iter != patchPointSet.end())
206  {
207  // If it is shared initialise the patchPatchPoints for this
208  // patch
209  if (!patchPatchPoints[patchi].size())
210  {
211  patchPatchPoints[patchi].setSize(ppmp.size());
212  patchPatchPointNormals[patchi].setSize(ppmp.size());
213  }
214 
215  // and add the entry
216  patchPatchPoints[patchi][pppi] = iter();
217  patchPatchPointNormals[patchi][pppi] = normals[pointi];
218  pppi++;
219  }
220  }
221 
222  // Resise the list of shared points and normals for the patch
223  // being considerd
224  patchPatchPoints[patchi].setSize(pppi);
225  patchPatchPointNormals[patchi].setSize(pppi);
226  }
227  }
228 
229  // Send the patchPatchPoints to the neighbouring processor
230 
231  OPstream toNeighbProc
232  (
234  neighbProcNo()
235  );
236 
237  toNeighbProc
238  << ppmp.size() // number of points for checking
239  << patchPatchPoints
240  << patchPatchPointNormals;
241 
242  if (debug)
243  {
244  Info<< "processorPointPatch::calcPatchPatchPoints() : "
245  << "constructed patch-patch points"
246  << endl;
247  }
248 }
249 
250 
251 void Foam::processorPointPatch::calcPatchPatchPoints()
252 {
253  // Get the patchPatchPoints from the neighbouring processor
254  IPstream fromNeighbProc
255  (
257  neighbProcNo()
258  );
259 
260  label nbrNPoints(readLabel(fromNeighbProc));
261  labelListList patchPatchPoints(fromNeighbProc);
262  List<List<vector> > patchPatchPointNormals(fromNeighbProc);
263 
264  pointBoundaryMesh& pbm = const_cast<pointBoundaryMesh&>(boundaryMesh());
265  const labelList& ppmp = meshPoints();
266 
267  // Simple check for the very rare situation when not the same number
268  // of points on both sides. This can happen with decomposed cyclics.
269  // If on one side the cyclic shares a point with proc faces coming from
270  // internal faces it will have a different number of points from
271  // the situation where the cyclic and the 'normal' proc faces are fully
272  // separate.
273  if (nbrNPoints != ppmp.size())
274  {
275  WarningIn("processorPointPatch::calcPatchPatchPoints()")
276  << "Processor patch " << name()
277  << " has " << ppmp.size() << " points; coupled patch has "
278  << nbrNPoints << " points." << endl
279  << " (usually due to decomposed cyclics)."
280  << " This might give problems" << endl
281  << " when using point fields (interpolation, mesh motion)."
282  << endl;
283  }
284 
285 
286 
287  // Loop over the patches looking for other patches that share points
288  forAll(patchPatchPoints, patchi)
289  {
290  const labelList& patchPoints = patchPatchPoints[patchi];
291  const List<vector>& patchPointNormals = patchPatchPointNormals[patchi];
292 
293  // If there are potentially shared points for the patch being considered
294  if (patchPoints.size())
295  {
296  // Get the current meshPoints list for the patch
297  facePointPatch& fpp = refCast<facePointPatch>(pbm[patchi]);
298  const labelList& fmp = fpp.meshPoints();
299  labelList& mp = fpp.meshPoints_;
300 
301  const vectorField& fnormals = fpp.pointNormals();
302  vectorField& normals = fpp.pointNormals_;
303 
304  // Create a HashSet of the point labels for the patch
305  Map<label> patchPointSet(2*fmp.size());
306 
307  forAll (fmp, ppi)
308  {
309  patchPointSet.insert(fmp[ppi], ppi);
310  }
311 
312  label nPoints = mp.size();
313  label lpi = 0;
314  bool resized = false;
315 
316  // For each potentially shared point...
317  forAll(patchPoints, ppi)
318  {
319  // Check if it is not already in the patch,
320  // i.e. not part of a face of the patch
321  if (!patchPointSet.found(ppmp[patchPoints[ppi]]))
322  {
323  // If it isn't already in the patch check if the local
324  // meshPoints is already set and if not initialise the
325  // meshPoints_ and pointNormals_
326  if (!resized)
327  {
328  if (!mp.size() && fmp.size())
329  {
330  mp = fmp;
331  normals = fnormals;
332 
333  nPoints = mp.size();
334  }
335 
336  mp.setSize(nPoints + patchPoints.size());
337  loneMeshPoints_.setSize(patchPoints.size());
338  normals.setSize(nPoints + patchPoints.size());
339  resized = true;
340  }
341 
342  // Add the new point to the patch
343  mp[nPoints] = ppmp[patchPoints[ppi]];
344  loneMeshPoints_[lpi++] = ppmp[patchPoints[ppi]];
345  normals[nPoints++] = patchPointNormals[ppi];
346  }
347  }
348 
349  // If the lists have been resized points have been added.
350  // Shrink the lists to the current size.
351  if (resized)
352  {
353  mp.setSize(nPoints);
354  loneMeshPoints_.setSize(lpi);
355  normals.setSize(nPoints);
356  }
357  }
358  }
359 }
360 
361 
362 void processorPointPatch::initMovePoints(const pointField&)
363 {}
364 
365 
366 void processorPointPatch::movePoints(const pointField&)
367 {}
368 
369 
370 void processorPointPatch::initUpdateMesh()
371 {
373  processorPointPatch::initGeometry();
374 }
375 
376 
377 void processorPointPatch::updateMesh()
378 {
380  processorPointPatch::calcGeometry();
381 }
382 
383 
384 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
385 
386 processorPointPatch::processorPointPatch
387 (
388  const polyPatch& patch,
389  const pointBoundaryMesh& bm
390 )
391 :
392  coupledFacePointPatch(patch, bm),
393  procPolyPatch_(refCast<const processorPolyPatch>(patch))
394 {}
395 
396 
397 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
398 
400 {}
401 
402 
403 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
404 
405 } // End namespace Foam
406 
407 // ************************ vim: set sw=4 sts=4 et: ************************ //