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 localData.insert(std::make_pair(pointI, labelledPoint(0,vector::zero)));
222 labelledPoint& lpd = localData[pointI];
224 forAllRow(pCells, pointI, pcI)
226 const label cellI = pCells(pointI, pcI);
229 lpd.coordinates() += centres[cellI];
232 forAllRow(pointAtProcs, pointI, procI)
234 const label neiProc = pointAtProcs(pointI, procI);
235 if( neiProc == Pstream::myProcNo() )
238 if( exchangeData.find(neiProc) == exchangeData.end() )
242 std::make_pair(neiProc, LongList<refLabelledPoint>())
246 //- add data to the list which will be sent to other processor
247 LongList<refLabelledPoint>& dts = exchangeData[neiProc];
248 dts.append(refLabelledPoint(globalPointLabel[pointI], lpd));
252 //- exchange data with other processors
253 LongList<refLabelledPoint> receivedData;
254 help::exchangeMap(exchangeData, receivedData);
256 forAll(receivedData, i)
258 const refLabelledPoint& lp = receivedData[i];
259 const label pointI = globalToLocal[lp.objectLabel()];
261 labelledPoint& lpd = localData[pointI];
263 lpd.pointLabel() += lp.lPoint().pointLabel();
264 lpd.coordinates() += lp.lPoint().coordinates();
267 //- create new positions of nodes
268 forAll(procPoints, pI)
270 const label pointI = procPoints[pI];
272 const labelledPoint& lp = localData[pointI];
274 if( lp.pointLabel() != 0 )
276 const point newP = lp.coordinates() / lp.pointLabel();
278 points[pointI] = newP;
284 std::map<label, LongList<labelledPoint> > check;
285 forAll(procPoints, pI)
287 const label pointI = procPoints[pI];
289 forAllRow(pointAtProcs, pointI, i)
291 const label procI = pointAtProcs(pointI, i);
292 if( procI == Pstream::myProcNo() )
294 if( check.find(procI) == check.end() )
296 check.insert(std::make_pair(procI, LongList<labelledPoint>()));
299 LongList<labelledPoint>& data = check[procI];
300 data.append(labelledPoint(globalPointLabel[pointI],points[pointI]));
304 LongList<labelledPoint> data;
305 help::exchangeMap(check, data);
309 const label pointI = globalToLocal[data[i].pointLabel()];
311 if( mag(points[pointI] - data[i].coordinates()) > SMALL )
312 Pout << "Crap " << globalPointLabel[pointI] << " coordinates "
313 << points[pointI] << " point there " << data[i] << endl;
318 void meshOptimizer::laplaceSmoother::laplacianWPCParallel
320 const labelLongList& procPoints
323 if( !Pstream::parRun() )
326 if( returnReduce(procPoints.size(), sumOp<label>()) == 0 )
329 const polyMeshGenAddressing& addressing = mesh_.addressingData();
330 const VRWGraph& pCells = mesh_.addressingData().pointCells();
331 const vectorField& centres = mesh_.addressingData().cellCentres();
332 const scalarField& volumes = mesh_.addressingData().cellVolumes();
333 pointFieldPMG& points = mesh_.points();
335 //- exchange data between processors
336 const labelLongList& globalPointLabel = addressing.globalPointLabel();
337 const VRWGraph& pointAtProcs = addressing.pointAtProcs();
338 const Map<label>& globalToLocal = addressing.globalToLocalPointAddressing();
340 //- create storage for the data
341 std::map<label, labelledPointScalar> localData;
343 //- create data which shall be exchanged with other processors
344 std::map<label, LongList<labelledPointScalar> > exchangeData;
345 forAll(procPoints, pI)
347 const label pointI = procPoints[pI];
354 labelledPointScalar(globalPointLabel[pointI], vector::zero, 0.)
357 labelledPointScalar& lps = localData[pointI];
359 forAllRow(pCells, pointI, pcI)
361 const label cellI = pCells(pointI, pcI);
363 const scalar w = Foam::max(volumes[cellI], VSMALL);
364 lps.coordinates() += w * centres[cellI];
365 lps.scalarValue() += w;
368 forAllRow(pointAtProcs, pointI, procI)
370 const label neiProc = pointAtProcs(pointI, procI);
371 if( neiProc == Pstream::myProcNo() )
374 if( exchangeData.find(neiProc) == exchangeData.end() )
378 std::make_pair(neiProc, LongList<labelledPointScalar>())
382 //- add data to the list which will be sent to other processor
383 LongList<labelledPointScalar>& dts = exchangeData[neiProc];
388 //- exchange data with other processors
389 LongList<labelledPointScalar> receivedData;
390 help::exchangeMap(exchangeData, receivedData);
392 forAll(receivedData, i)
394 const labelledPointScalar& lps = receivedData[i];
395 const label pointI = globalToLocal[lps.pointLabel()];
397 labelledPointScalar& lp = localData[pointI];
399 lp.scalarValue() += lps.scalarValue();
400 lp.coordinates() += lps.coordinates();
403 //- create new positions of nodes
404 forAll(procPoints, pI)
406 const label pointI = procPoints[pI];
408 const labelledPointScalar& lp = localData[pointI];
410 if( lp.pointLabel() != 0 )
412 const point newP = lp.coordinates() / lp.scalarValue();
414 points[pointI] = newP;
420 std::map<label, LongList<labelledPoint> > check;
421 forAll(procPoints, pI)
423 const label pointI = procPoints[pI];
425 forAllRow(pointAtProcs, pointI, i)
427 const label procI = pointAtProcs(pointI, i);
428 if( procI == Pstream::myProcNo() )
430 if( check.find(procI) == check.end() )
432 check.insert(std::make_pair(procI, LongList<labelledPoint>()));
435 LongList<labelledPoint>& data = check[procI];
436 data.append(labelledPoint(globalPointLabel[pointI],points[pointI]));
440 LongList<labelledPoint> data;
441 help::exchangeMap(check, data);
445 const label pointI = globalToLocal[data[i].pointLabel()];
447 if( mag(points[pointI] - data[i].coordinates()) > SMALL )
448 Pout << "Crap " << globalPointLabel[pointI] << " coordinates "
449 << points[pointI] << " point there " << data[i] << endl;
454 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
456 } // End namespace Foam
458 // ************************************************************************* //