1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
27 #include "freeSurface.H"
28 #include "primitivePatchInterpolation.H"
29 #include "emptyFaPatch.H"
30 #include "wedgeFaPatch.H"
31 #include "PstreamCombineReduceOps.H"
32 #include "coordinateSystem.H"
33 #include "scalarMatrices.H"
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
44 tmp<vectorField> freeSurface::pointDisplacement(const scalarField& deltaH)
46 const pointField& points = aMesh().patch().localPoints();
47 const labelListList& pointFaces = aMesh().patch().pointFaces();
49 controlPoints() += facesDisplacementDir()*deltaH;
51 tmp<vectorField> tdisplacement
60 vectorField& displacement = tdisplacement();
63 // Calculate displacement of internal points
64 const vectorField& pointNormals = aMesh().pointAreaNormals();
65 const edgeList& edges = aMesh().patch().edges();
66 labelList internalPoints = aMesh().internalPoints();
68 forAll (internalPoints, pointI)
70 label curPoint = internalPoints[pointI];
72 const labelList& curPointFaces = pointFaces[curPoint];
74 vectorField lsPoints(curPointFaces.size(), vector::zero);
76 for (label i=0; i<curPointFaces.size(); i++)
78 label curFace = curPointFaces[i];
80 lsPoints[i] = controlPoints()[curFace];
83 vectorField pointAndNormal =
88 pointNormals[curPoint]
91 vector& P = pointAndNormal[0];
92 vector& N = pointAndNormal[1];
94 displacement[curPoint] =
95 pointsDisplacementDir()[curPoint]
96 *((P - points[curPoint])&N)
97 /(pointsDisplacementDir()[curPoint]&N);
101 // Mirror control points
102 FieldField<Field, vector> patchMirrorPoints(aMesh().boundary().size());
104 forAll(patchMirrorPoints, patchI)
106 patchMirrorPoints.set
111 aMesh().boundary()[patchI].faPatch::size(),
117 aMesh().boundary()[patchI].ngbPolyPatchFaceNormals();
119 const labelList peFaces =
123 aMesh().boundary()[patchI].faPatch::size(),
124 aMesh().boundary()[patchI].start()
127 const labelList& pEdges = aMesh().boundary()[patchI];
129 vectorField peCentres(pEdges.size(), vector::zero);
130 forAll(peCentres, edgeI)
133 edges[pEdges[edgeI]].centre(points);
137 vectorField(controlPoints(), peFaces)
140 patchMirrorPoints[patchI] =
141 peCentres + ((I - 2*N*N)&delta);
145 // Calculate displacement of boundary points
146 labelList boundaryPoints = aMesh().boundaryPoints();
148 const labelListList& edgeFaces = aMesh().patch().edgeFaces();
149 const labelListList& pointEdges = aMesh().patch().pointEdges();
151 forAll (boundaryPoints, pointI)
153 label curPoint = boundaryPoints[pointI];
155 if (motionPointsMask()[curPoint] == 1)
157 // Calculating mirror points
158 const labelList& curPointEdges = pointEdges[curPoint];
160 vectorField mirrorPoints(2, vector::zero);
164 forAll (curPointEdges, edgeI)
166 label curEdge = curPointEdges[edgeI];
168 if(edgeFaces[curEdge].size() == 1)
172 forAll(aMesh().boundary(), patchI)
174 const labelList& pEdges =
175 aMesh().boundary()[patchI];
176 label index = findIndex(pEdges, curEdge);
185 mirrorPoints[++counter] =
186 patchMirrorPoints[patchID][edgeID];
190 // Calculating LS plane fit
191 const labelList& curPointFaces = pointFaces[curPoint];
195 curPointFaces.size() + mirrorPoints.size(),
201 for (label i=0; i<curPointFaces.size(); i++)
203 label curFace = curPointFaces[i];
205 lsPoints[++counter] = controlPoints()[curFace];
208 for (label i=0; i<mirrorPoints.size(); i++)
210 lsPoints[++counter] = mirrorPoints[i];
213 vectorField pointAndNormal =
214 lsPlanePointAndNormal
218 pointNormals[curPoint]
221 vector& P = pointAndNormal[0];
222 vector& N = pointAndNormal[1];
224 displacement[curPoint] =
225 pointsDisplacementDir()[curPoint]
226 *((P - points[curPoint])&N)
227 /(pointsDisplacementDir()[curPoint]&N);
232 // Calculate displacement of axis point
233 forAll (aMesh().boundary(), patchI)
237 aMesh().boundary()[patchI].type()
238 == wedgeFaPatch::typeName
241 const wedgeFaPatch& wedgePatch =
242 refCast<const wedgeFaPatch>(aMesh().boundary()[patchI]);
244 if(wedgePatch.axisPoint() > -1)
246 label axisPoint = wedgePatch.axisPoint();
248 displacement[axisPoint] =
249 pointsDisplacementDir()[axisPoint]
251 pointsDisplacementDir()[axisPoint]
253 controlPoints()[pointFaces[axisPoint][0]]
262 // Calculate displacement of processor patch points
263 forAll (aMesh().boundary(), patchI)
267 aMesh().boundary()[patchI].type()
268 == processorFaPatch::typeName
271 const processorFaPatch& procPatch =
272 refCast<const processorFaPatch>(aMesh().boundary()[patchI]);
274 const labelList& patchPointLabels =
275 procPatch.pointLabels();
277 FieldField<Field, vector> lsPoints(patchPointLabels.size());
278 forAll(lsPoints, pointI)
280 lsPoints.set(pointI, new vectorField(0, vector::zero));
283 const labelList& nonGlobalPatchPoints =
284 procPatch.nonGlobalPatchPoints();
286 forAll(nonGlobalPatchPoints, pointI)
288 label curPatchPoint =
289 nonGlobalPatchPoints[pointI];
292 patchPointLabels[curPatchPoint];
294 const labelList& curPointFaces = pointFaces[curPoint];
296 lsPoints[curPatchPoint].setSize(curPointFaces.size());
298 forAll(curPointFaces, faceI)
300 label curFace = curPointFaces[faceI];
302 lsPoints[curPatchPoint][faceI] = controlPoints()[curFace];
305 # include "boundaryProcessorFaPatchPoints.H"
308 scalar lsPointsSize = 0;
309 forAll(lsPoints, pointI)
312 2*lsPoints[pointI].size()*sizeof(vector);
315 // Parallel data exchange
317 OPstream toNeighbProc
320 procPatch.neighbProcNo(),
324 toNeighbProc << lsPoints;
327 FieldField<Field, vector> ngbLsPoints(patchPointLabels.size());
330 IPstream fromNeighbProc
333 procPatch.neighbProcNo(),
337 fromNeighbProc >> ngbLsPoints;
340 forAll(nonGlobalPatchPoints, pointI)
342 label curPatchPoint =
343 nonGlobalPatchPoints[pointI];
346 patchPointLabels[curPatchPoint];
348 label curNgbPoint = procPatch.neighbPoints()[curPatchPoint];
350 vectorField allLsPoints
352 lsPoints[curPatchPoint].size()
353 + ngbLsPoints[curNgbPoint].size(),
358 forAll(lsPoints[curPatchPoint], pointI)
360 allLsPoints[++counter] = lsPoints[curPatchPoint][pointI];
362 forAll(ngbLsPoints[curNgbPoint], pointI)
364 allLsPoints[++counter] = ngbLsPoints[curNgbPoint][pointI];
367 vectorField pointAndNormal =
368 lsPlanePointAndNormal
372 pointNormals[curPoint]
375 vector& P = pointAndNormal[0];
376 vector& N = pointAndNormal[1];
378 if (motionPointsMask()[curPoint] != 0)
380 displacement[curPoint] =
381 pointsDisplacementDir()[curPoint]
382 *((P - points[curPoint])&N)
383 /(pointsDisplacementDir()[curPoint]&N);
390 // Calculate displacement of global processor patch points
391 if (aMesh().globalData().nGlobalPoints() > 0)
393 const labelList& spLabels =
394 aMesh().globalData().sharedPointLabels();
396 const labelList& addr = aMesh().globalData().sharedPointAddr();
398 for (label k=0; k<aMesh().globalData().nGlobalPoints(); k++)
400 List<List<vector> > procLsPoints(Pstream::nProcs());
402 label curSharedPointIndex = findIndex(addr, k);
404 if (curSharedPointIndex != -1)
406 label curPoint = spLabels[curSharedPointIndex];
408 const labelList& curPointFaces = pointFaces[curPoint];
410 procLsPoints[Pstream::myProcNo()] =
411 List<vector>(curPointFaces.size());
413 forAll (curPointFaces, faceI)
415 label curFace = curPointFaces[faceI];
417 procLsPoints[Pstream::myProcNo()][faceI] =
418 controlPoints()[curFace];
422 Pstream::gatherList(procLsPoints);
423 Pstream::scatterList(procLsPoints);
425 if (curSharedPointIndex != -1)
427 label curPoint = spLabels[curSharedPointIndex];
429 label nAllPoints = 0;
430 forAll(procLsPoints, procI)
432 nAllPoints += procLsPoints[procI].size();
435 vectorField allPoints(nAllPoints, vector::zero);
438 forAll(procLsPoints, procI)
440 forAll(procLsPoints[procI], pointI)
442 allPoints[counter++] =
443 procLsPoints[procI][pointI];
447 vectorField pointAndNormal =
448 lsPlanePointAndNormal
452 pointNormals[curPoint]
455 const vector& P = pointAndNormal[0];
456 const vector& N = pointAndNormal[1];
458 displacement[curPoint] =
459 pointsDisplacementDir()[curPoint]
460 *((P - points[curPoint])&N)
461 /(pointsDisplacementDir()[curPoint]&N);
466 return tdisplacement;
470 tmp<vectorField> freeSurface::lsPlanePointAndNormal
472 const vectorField& points,
473 const vector& origin,
478 vector dir = (points[0] - origin);
479 dir -= axis*(axis&dir);
481 coordinateSystem cs("cs", origin, axis, dir);
483 vectorField localPoints = cs.localPosition(points);
484 scalarField W = 1.0/(mag(points - origin) + SMALL);
486 scalarRectangularMatrix M
493 for (label i=0; i<localPoints.size(); i++)
495 M[i][0] = localPoints[i].x();
496 M[i][1] = localPoints[i].y();
500 scalarSquareMatrix MtM(3, 0.0);
501 for (label i = 0; i < MtM.n(); i++)
503 for (label j = 0; j < MtM.m(); j++)
505 for (label k = 0; k < M.n(); k++)
507 MtM[i][j] += M[k][i]*M[k][j]*W[k];
512 scalarField MtR(3, 0);
513 for (label i = 0; i < MtR.size(); i++)
515 for (label j = 0; j < M.n(); j++)
517 MtR[i] += M[j][i]*localPoints[j].z()*W[j];
521 scalarSquareMatrix::LUsolve(MtM, MtR);
523 vector n0 = vector(-MtR[0], -MtR[1], 1);
524 n0 = cs.globalVector(n0);
527 vector p0 = vector(0, 0, MtR[2]);
528 p0 = cs.globalPosition(p0);
530 tmp<vectorField> pointAndNormal
532 new vectorField(2, vector::zero)
535 pointAndNormal()[0] = p0;
536 pointAndNormal()[1] = n0;
538 return pointAndNormal;
542 // tmp<vectorField> freeSurface::pointDisplacementSM()
544 // const pointField& points = aMesh().patch().localPoints();
545 // const labelListList& pointFaces = aMesh().patch().pointFaces();
548 // tmp<vectorField> tdisplacement
557 // vectorField& displacement = tdisplacement();
560 // forAll (pointFaces, pointI)
562 // scalar weightsSum = 0.0;
564 // const labelList& curPointFaces = pointFaces[pointI];
566 // forAll (curPointFaces, faceI)
568 // label curFace = curPointFaces[faceI];
570 // scalar weight = 1.0/mag
573 // - controlPoints()[curFace]
576 // displacement[pointI] += weight*controlPoints()[curFace];
578 // weightsSum += weight;
581 // displacement[pointI] /= weightsSum;
583 // displacement[pointI] -= points[pointI];
587 // displacement = motionPointsMask()*
588 // (pointsDisplacementDir()&displacement)*
589 // pointsDisplacementDir();
592 // return tdisplacement;
596 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
598 } // End namespace Foam
600 // ************************************************************************* //