1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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.
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
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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "enrichedPatch.H"
27 #include "DynamicList.H"
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 const Foam::label Foam::enrichedPatch::enrichedFaceRatio_ = 3;
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
36 void Foam::enrichedPatch::calcEnrichedFaces
38 const labelListList& pointsIntoMasterEdges,
39 const labelListList& pointsIntoSlaveEdges,
40 const pointField& projectedSlavePoints
43 if (enrichedFacesPtr_)
47 "void enrichedPatch::calcEnrichedFaces\n"
49 " const labelListList& pointsIntoMasterEdges,\n"
50 " const labelListList& pointsIntoSlaveEdges,\n"
51 " const pointField& projectedSlavePoints\n"
53 ) << "Enriched faces already calculated."
57 // Create a list of enriched faces
59 // 1) Grab the original face and start from point zero.
60 // 2) If the point has been merged away, grab the merge label;
61 // otherwise, keep the original label.
62 // 3) Go to the next edge. Collect all the points to be added along
63 // the edge; order them in the necessary direction and insert onto the
65 // 4) Grab the next point and return on step 2.
66 enrichedFacesPtr_ = new faceList(masterPatch_.size() + slavePatch_.size());
67 faceList& enrichedFaces = *enrichedFacesPtr_;
69 label nEnrichedFaces = 0;
71 const pointField& masterLocalPoints = masterPatch_.localPoints();
72 const faceList& masterLocalFaces = masterPatch_.localFaces();
73 const labelListList& masterFaceEdges = masterPatch_.faceEdges();
75 const faceList& slaveLocalFaces = slavePatch_.localFaces();
76 const labelListList& slaveFaceEdges = slavePatch_.faceEdges();
78 // For correct functioning of the enrichedPatch class, the slave
79 // faces need to be inserted first. See comments in
82 // Get reference to the point merge map
83 const Map<label>& pmm = pointMergeMap();
85 // Add slave faces into the enriched faces list
87 forAll(slavePatch_, faceI)
89 const face oldFace = slavePatch_[faceI];
90 const face oldLocalFace = slaveLocalFaces[faceI];
91 // Info<< "old slave face " << faceI << ": " << oldFace << endl;
92 const labelList& curEdges = slaveFaceEdges[faceI];
94 DynamicList<label> newFace(oldFace.size()*enrichedFaceRatio_);
96 // Note: The number of points and edges in a face is always identical
97 // so both can be done is the same loop
101 Map<label>::const_iterator mpIter =
102 pmm.find(oldFace[i]);
104 if (mpIter == pmm.end())
107 newFace.append(oldFace[i]);
109 // Add the projected point into the patch support
112 oldFace[i], // Global label of point
113 projectedSlavePoints[oldLocalFace[i]] // Projected position
119 newFace.append(mpIter());
121 // Add the projected point into the patch support
124 mpIter(), // Merged global label of point
125 projectedSlavePoints[oldLocalFace[i]] // Projected position
129 // Grab the edge points
131 const labelList& slavePointsOnEdge =
132 pointsIntoSlaveEdges[curEdges[i]];
134 // Info<< "slavePointsOnEdge for "
135 // << curEdges[i] << ": " << slavePointsOnEdge
138 // If there are no points on the edge, skip everything
139 // If there is only one point, no need for sorting
140 if (slavePointsOnEdge.size())
142 // Sort edge points in order
143 scalarField edgePointWeights(slavePointsOnEdge.size());
144 const point& startPoint = projectedSlavePoints[oldLocalFace[i]];
147 projectedSlavePoints[oldLocalFace.nextLabel(i)]
150 scalar magSqrE = magSqr(e);
160 "void enrichedPatch::calcEnrichedFaces\n"
162 " const labelListList& pointsIntoMasterEdges,\n"
163 " const labelListList& pointsIntoSlaveEdges,\n"
164 " const pointField& projectedSlavePoints\n"
166 ) << "Zero length edge in slave patch for face " << i
167 << ". This is not allowed."
168 << abort(FatalError);
171 pointField slavePosOnEdge(slavePointsOnEdge.size());
173 forAll(slavePointsOnEdge, edgePointI)
175 slavePosOnEdge[edgePointI] =
176 pointMap().find(slavePointsOnEdge[edgePointI])();
178 edgePointWeights[edgePointI] =
179 (e & (slavePosOnEdge[edgePointI] - startPoint));
184 // Check weights: all new points should be on the edge
185 if (min(edgePointWeights) < 0 || max(edgePointWeights) > 1)
189 "void enrichedPatch::calcEnrichedFaces\n"
191 " const labelListList& pointsIntoMasterEdges,\n"
192 " const labelListList& pointsIntoSlaveEdges,\n"
193 " const pointField& projectedSlavePoints\n"
195 ) << "Invalid point edge weights. Some of points are"
196 << " not on the edge for edge " << curEdges[i]
197 << " of face " << faceI << " in slave patch." << nl
198 << "Min weight: " << min(edgePointWeights)
199 << " Max weight: " << max(edgePointWeights)
200 << abort(FatalError);
204 // Go through the points and collect them based on
205 // weights from lower to higher. This gives the
206 // correct order of points along the edge.
207 forAll(edgePointWeights, passI)
209 // Max weight can only be one, so the sorting is
210 // done by elimination.
211 label nextPoint = -1;
214 forAll(edgePointWeights, wI)
216 if (edgePointWeights[wI] < dist)
218 dist = edgePointWeights[wI];
223 // Insert the next point and reset its weight to exclude it
225 newFace.append(slavePointsOnEdge[nextPoint]);
226 edgePointWeights[nextPoint] = GREAT;
228 // Add the point into patch support
231 slavePointsOnEdge[nextPoint],
232 slavePosOnEdge[nextPoint]
237 // Info<< "New slave face " << faceI << ": " << newFace << endl;
239 // Add the new face to the list
240 enrichedFaces[nEnrichedFaces].transfer(newFace);
244 // Add master faces into the enriched faces list
246 forAll(masterPatch_, faceI)
248 const face& oldFace = masterPatch_[faceI];
249 const face& oldLocalFace = masterLocalFaces[faceI];
250 // Info<< "old master face: " << oldFace << endl;
251 const labelList& curEdges = masterFaceEdges[faceI];
253 DynamicList<label> newFace(oldFace.size()*enrichedFaceRatio_);
255 // Note: The number of points and edges in a face is always identical
256 // so both can be done is the same loop
260 Map<label>::const_iterator mpIter =
261 pmm.find(oldFace[i]);
263 if (mpIter == pmm.end())
266 newFace.append(oldFace[i]);
268 // Add the point into patch support
272 masterLocalPoints[oldLocalFace[i]]
278 newFace.append(mpIter());
280 // Add the point into support
281 pointMap().insert(mpIter(), masterLocalPoints[oldLocalFace[i]]);
284 // Grab the edge points
286 const labelList& masterPointsOnEdge =
287 pointsIntoMasterEdges[curEdges[i]];
289 // If there are no points on the edge, skip everything
290 // If there is only one point, no need for sorting
291 if (masterPointsOnEdge.size())
293 // Sort edge points in order
294 scalarField edgePointWeights(masterPointsOnEdge.size());
295 const point& startPoint = masterLocalPoints[oldLocalFace[i]];
298 masterLocalPoints[oldLocalFace.nextLabel(i)]
301 scalar magSqrE = magSqr(e);
311 "void enrichedPatch::calcEnrichedFaces\n"
313 " const labelListList& pointsIntoMasterEdges,\n"
314 " const labelListList& pointsIntoSlaveEdges,\n"
315 " const pointField& projectedSlavePoints\n"
317 ) << "Zero length edge in master patch for face " << i
318 << ". This is not allowed."
319 << abort(FatalError);
322 pointField masterPosOnEdge(masterPointsOnEdge.size());
324 forAll(masterPointsOnEdge, edgePointI)
326 masterPosOnEdge[edgePointI] =
327 pointMap().find(masterPointsOnEdge[edgePointI])();
329 edgePointWeights[edgePointI] =
330 (e & (masterPosOnEdge[edgePointI] - startPoint));
335 // Check weights: all new points should be on the edge
336 if (min(edgePointWeights) < 0 || max(edgePointWeights) > 1)
340 "void enrichedPatch::calcEnrichedFaces\n"
342 " const labelListList& pointsIntoMasterEdges,\n"
343 " const labelListList& pointsIntoSlaveEdges,\n"
344 " const pointField& projectedSlavePoints\n"
346 ) << "Invalid point edge weights. Some of points are"
347 << " not on the edge for edge " << curEdges[i]
348 << " of face " << faceI << " in master patch." << nl
349 << "Min weight: " << min(edgePointWeights)
350 << " Max weight: " << max(edgePointWeights)
351 << abort(FatalError);
355 // Go through the points and collect them based on
356 // weights from lower to higher. This gives the
357 // correct order of points along the edge.
358 forAll(edgePointWeights, passI)
360 // Max weight can only be one, so the sorting is
361 // done by elimination.
362 label nextPoint = -1;
365 forAll(edgePointWeights, wI)
367 if (edgePointWeights[wI] < dist)
369 dist = edgePointWeights[wI];
374 // Insert the next point and reset its weight to exclude it
376 newFace.append(masterPointsOnEdge[nextPoint]);
377 edgePointWeights[nextPoint] = GREAT;
379 // Add the point into patch support
382 masterPointsOnEdge[nextPoint],
383 masterPosOnEdge[nextPoint]
388 // Info<< "New master face: " << newFace << endl;
390 // Add the new face to the list
391 enrichedFaces[nEnrichedFaces].transfer(newFace);
395 // Check the support for the enriched patch
400 Info<< "Enriched patch support OK. Slave faces: "
401 << slavePatch_.size() << " Master faces: "
402 << masterPatch_.size() << endl;
408 "void enrichedPatch::calcEnrichedFaces\n"
410 " const labelListList& pointsIntoMasterEdges,\n"
411 " const labelListList& pointsIntoSlaveEdges,\n"
412 " const pointField& projectedSlavePoints\n"
414 ) << "Error in enriched patch support"
415 << abort(FatalError);
421 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
423 const Foam::faceList& Foam::enrichedPatch::enrichedFaces() const
425 if (!enrichedFacesPtr_)
427 FatalErrorIn("const faceList& enrichedPatch::enrichedFaces() const")
428 << "Enriched faces not available yet. Please use "
429 << "void enrichedPatch::calcEnrichedFaces\n"
431 << " const labelListList& pointsIntoMasterEdges,\n"
432 << " const labelListList& pointsIntoSlaveEdges,\n"
433 << " const pointField& projectedSlavePoints\n"
435 << " before trying to access faces."
436 << abort(FatalError);
439 return *enrichedFacesPtr_;
443 // ************************************************************************* //