1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | cfMesh: A library for mesh generation
5 \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6 \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of cfMesh.
11 cfMesh is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
16 cfMesh 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
21 You should have received a copy of the GNU General Public License
22 along with cfMesh. If not, see <http://www.gnu.org/licenses/>.
26 \*---------------------------------------------------------------------------*/
28 #include "demandDrivenData.H"
29 #include "meshOptimizer.H"
30 #include "polyMeshGenAddressing.H"
32 #include "refLabelledPoint.H"
33 #include "labelledPointScalar.H"
34 #include "helperFunctionsPar.H"
40 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
47 void meshOptimizer::laplaceSmoother::laplacianParallel
49 const labelLongList& procPoints,
50 const bool smoothOnlySurfaceNodes
53 if( !Pstream::parRun() )
56 if( returnReduce(procPoints.size(), sumOp<label>()) == 0 )
59 const polyMeshGenAddressing& addressing = mesh_.addressingData();
60 const VRWGraph& pPoints = mesh_.addressingData().pointPoints();
61 pointFieldPMG& points = mesh_.points();
63 //- exchange data between processors
64 const labelLongList& globalPointLabel = addressing.globalPointLabel();
65 const VRWGraph& pointAtProcs = addressing.pointAtProcs();
66 const Map<label>& globalToLocal = addressing.globalToLocalPointAddressing();
68 //- create storage for the data
69 std::map<label, labelledPoint> localData;
71 //- create data which shall be exchanged with other processors
72 std::map<label, LongList<refLabelledPoint> > exchangeData;
73 forAll(procPoints, pI)
75 const label pointI = procPoints[pI];
77 localData.insert(std::make_pair(pointI, labelledPoint(0,vector::zero)));
78 labelledPoint& lpd = localData[pointI];
80 forAllRow(pPoints, pointI, ppI)
82 const label nei = pPoints(pointI, ppI);
84 if( smoothOnlySurfaceNodes && (vertexLocation_[nei] & INSIDE) )
87 if( pointAtProcs.sizeOfRow(nei) != 0 )
89 label pMin(Pstream::nProcs());
90 forAllRow(pointAtProcs, nei, procI)
92 const label procJ = pointAtProcs(nei, procI);
93 if( (procJ < pMin) && pointAtProcs.contains(pointI, procJ) )
97 if( pMin != Pstream::myProcNo() )
102 lpd.coordinates() += points[nei];
105 forAllRow(pointAtProcs, pointI, procI)
107 const label neiProc = pointAtProcs(pointI, procI);
108 if( neiProc == Pstream::myProcNo() )
111 if( exchangeData.find(neiProc) == exchangeData.end() )
115 std::make_pair(neiProc, LongList<refLabelledPoint>())
119 //- add data to the list which will be sent to other processor
120 LongList<refLabelledPoint>& dts = exchangeData[neiProc];
121 dts.append(refLabelledPoint(globalPointLabel[pointI], lpd));
125 //- exchange data with other processors
126 LongList<refLabelledPoint> receivedData;
127 help::exchangeMap(exchangeData, receivedData);
129 forAll(receivedData, i)
131 const refLabelledPoint& lp = receivedData[i];
132 const label pointI = globalToLocal[lp.objectLabel()];
134 labelledPoint& lpd = localData[pointI];
136 lpd.pointLabel() += lp.lPoint().pointLabel();
137 lpd.coordinates() += lp.lPoint().coordinates();
140 //- create new positions of nodes
141 forAll(procPoints, pI)
143 const label pointI = procPoints[pI];
145 const labelledPoint& lp = localData[pointI];
147 if( lp.pointLabel() != 0 )
149 const point newP = lp.coordinates() / lp.pointLabel();
151 points[pointI] = newP;
157 std::map<label, LongList<labelledPoint> > check;
158 forAll(procPoints, pI)
160 const label pointI = procPoints[pI];
162 forAllRow(pointAtProcs, pointI, i)
164 const label procI = pointAtProcs(pointI, i);
165 if( procI == Pstream::myProcNo() )
167 if( check.find(procI) == check.end() )
169 check.insert(std::make_pair(procI, LongList<labelledPoint>()));
172 LongList<labelledPoint>& data = check[procI];
173 data.append(labelledPoint(globalPointLabel[pointI],points[pointI]));
177 LongList<labelledPoint> data;
178 help::exchangeMap(check, data);
182 const label pointI = globalToLocal[data[i].pointLabel()];
184 if( mag(points[pointI] - data[i].coordinates()) > SMALL )
185 Pout << "Crap " << globalPointLabel[pointI] << " coordinates "
186 << points[pointI] << " point there " << data[i] << endl;
191 void meshOptimizer::laplaceSmoother::laplacianPCParallel
193 const labelLongList& procPoints
196 if( !Pstream::parRun() )
199 if( returnReduce(procPoints.size(), sumOp<label>()) == 0 )
202 const polyMeshGenAddressing& addressing = mesh_.addressingData();
203 const VRWGraph& pCells = mesh_.addressingData().pointCells();
204 const vectorField& centres = mesh_.addressingData().cellCentres();
205 pointFieldPMG& points = mesh_.points();
207 //- exchange data between processors
208 const labelLongList& globalPointLabel = addressing.globalPointLabel();
209 const VRWGraph& pointAtProcs = addressing.pointAtProcs();
210 const Map<label>& globalToLocal = addressing.globalToLocalPointAddressing();
212 //- create storage for the data
213 std::map<label, labelledPoint> localData;
215 //- create data which shall be exchanged with other processors
216 std::map<label, LongList<refLabelledPoint> > exchangeData;
217 forAll(procPoints, pI)
219 const label pointI = procPoints[pI];
221 if( vertexLocation_[pointI] & LOCKED )
224 localData.insert(std::make_pair(pointI, labelledPoint(0,vector::zero)));
225 labelledPoint& lpd = localData[pointI];
227 forAllRow(pCells, pointI, pcI)
229 const label cellI = pCells(pointI, pcI);
232 lpd.coordinates() += centres[cellI];
235 forAllRow(pointAtProcs, pointI, procI)
237 const label neiProc = pointAtProcs(pointI, procI);
238 if( neiProc == Pstream::myProcNo() )
241 if( exchangeData.find(neiProc) == exchangeData.end() )
245 std::make_pair(neiProc, LongList<refLabelledPoint>())
249 //- add data to the list which will be sent to other processor
250 LongList<refLabelledPoint>& dts = exchangeData[neiProc];
251 dts.append(refLabelledPoint(globalPointLabel[pointI], lpd));
255 //- exchange data with other processors
256 LongList<refLabelledPoint> receivedData;
257 help::exchangeMap(exchangeData, receivedData);
259 forAll(receivedData, i)
261 const refLabelledPoint& lp = receivedData[i];
262 const label pointI = globalToLocal[lp.objectLabel()];
264 labelledPoint& lpd = localData[pointI];
266 lpd.pointLabel() += lp.lPoint().pointLabel();
267 lpd.coordinates() += lp.lPoint().coordinates();
270 //- create new positions of nodes
271 forAll(procPoints, pI)
273 const label pointI = procPoints[pI];
275 const labelledPoint& lp = localData[pointI];
277 if( lp.pointLabel() != 0 )
279 const point newP = lp.coordinates() / lp.pointLabel();
281 points[pointI] = newP;
287 std::map<label, LongList<labelledPoint> > check;
288 forAll(procPoints, pI)
290 const label pointI = procPoints[pI];
292 forAllRow(pointAtProcs, pointI, i)
294 const label procI = pointAtProcs(pointI, i);
295 if( procI == Pstream::myProcNo() )
297 if( check.find(procI) == check.end() )
299 check.insert(std::make_pair(procI, LongList<labelledPoint>()));
302 LongList<labelledPoint>& data = check[procI];
303 data.append(labelledPoint(globalPointLabel[pointI],points[pointI]));
307 LongList<labelledPoint> data;
308 help::exchangeMap(check, data);
312 const label pointI = globalToLocal[data[i].pointLabel()];
314 if( mag(points[pointI] - data[i].coordinates()) > SMALL )
315 Pout << "Crap " << globalPointLabel[pointI] << " coordinates "
316 << points[pointI] << " point there " << data[i] << endl;
321 void meshOptimizer::laplaceSmoother::laplacianWPCParallel
323 const labelLongList& procPoints
326 if( !Pstream::parRun() )
329 if( returnReduce(procPoints.size(), sumOp<label>()) == 0 )
332 const polyMeshGenAddressing& addressing = mesh_.addressingData();
333 const VRWGraph& pCells = mesh_.addressingData().pointCells();
334 const vectorField& centres = mesh_.addressingData().cellCentres();
335 const scalarField& volumes = mesh_.addressingData().cellVolumes();
336 pointFieldPMG& points = mesh_.points();
338 //- exchange data between processors
339 const labelLongList& globalPointLabel = addressing.globalPointLabel();
340 const VRWGraph& pointAtProcs = addressing.pointAtProcs();
341 const Map<label>& globalToLocal = addressing.globalToLocalPointAddressing();
343 //- create storage for the data
344 std::map<label, labelledPointScalar> localData;
346 //- create data which shall be exchanged with other processors
347 std::map<label, LongList<labelledPointScalar> > exchangeData;
348 forAll(procPoints, pI)
350 const label pointI = procPoints[pI];
352 if( vertexLocation_[pointI] & LOCKED )
360 labelledPointScalar(globalPointLabel[pointI], vector::zero, 0.)
363 labelledPointScalar& lps = localData[pointI];
365 forAllRow(pCells, pointI, pcI)
367 const label cellI = pCells(pointI, pcI);
369 const scalar w = Foam::max(volumes[cellI], VSMALL);
370 lps.coordinates() += w * centres[cellI];
371 lps.scalarValue() += w;
374 forAllRow(pointAtProcs, pointI, procI)
376 const label neiProc = pointAtProcs(pointI, procI);
377 if( neiProc == Pstream::myProcNo() )
380 if( exchangeData.find(neiProc) == exchangeData.end() )
384 std::make_pair(neiProc, LongList<labelledPointScalar>())
388 //- add data to the list which will be sent to other processor
389 LongList<labelledPointScalar>& dts = exchangeData[neiProc];
394 //- exchange data with other processors
395 LongList<labelledPointScalar> receivedData;
396 help::exchangeMap(exchangeData, receivedData);
398 forAll(receivedData, i)
400 const labelledPointScalar& lps = receivedData[i];
401 const label pointI = globalToLocal[lps.pointLabel()];
403 labelledPointScalar& lp = localData[pointI];
405 lp.scalarValue() += lps.scalarValue();
406 lp.coordinates() += lps.coordinates();
409 //- create new positions of nodes
410 forAll(procPoints, pI)
412 const label pointI = procPoints[pI];
414 if( vertexLocation_[pointI] & LOCKED )
417 const labelledPointScalar& lp = localData[pointI];
419 if( lp.pointLabel() != 0 )
421 const point newP = lp.coordinates() / lp.scalarValue();
423 points[pointI] = newP;
429 std::map<label, LongList<labelledPoint> > check;
430 forAll(procPoints, pI)
432 const label pointI = procPoints[pI];
434 forAllRow(pointAtProcs, pointI, i)
436 const label procI = pointAtProcs(pointI, i);
437 if( procI == Pstream::myProcNo() )
439 if( check.find(procI) == check.end() )
441 check.insert(std::make_pair(procI, LongList<labelledPoint>()));
444 LongList<labelledPoint>& data = check[procI];
445 data.append(labelledPoint(globalPointLabel[pointI],points[pointI]));
449 LongList<labelledPoint> data;
450 help::exchangeMap(check, data);
454 const label pointI = globalToLocal[data[i].pointLabel()];
456 if( mag(points[pointI] - data[i].coordinates()) > SMALL )
457 Pout << "Crap " << globalPointLabel[pointI] << " coordinates "
458 << points[pointI] << " point there " << data[i] << endl;
463 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
465 } // End namespace Foam
467 // ************************************************************************* //