1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 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, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 Calculate enriched faces
29 Hrvoje Jasak, Wikki Ltd. All rights reserved. Copyright Hrvoje Jasak.
31 \*---------------------------------------------------------------------------*/
33 #include "enrichedPatch.H"
34 #include "DynamicList.H"
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 const Foam::label Foam::enrichedPatch::enrichedFaceRatio_ = 3;
41 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 void Foam::enrichedPatch::calcEnrichedFaces
45 const labelListList& pointsIntoMasterEdges,
46 const labelListList& pointsIntoSlaveEdges,
47 const pointField& projectedSlavePoints
50 if (enrichedFacesPtr_)
54 "void enrichedPatch::calcEnrichedFaces\n"
56 " const labelListList& pointsIntoMasterEdges,\n"
57 " const labelListList& pointsIntoSlaveEdges,\n"
58 " const pointField& projectedSlavePoints\n"
60 ) << "Enriched faces already calculated."
64 // Create a list of enriched faces
66 // 1) Grab the original face and start from point zero.
67 // 2) If the point has been merged away, grab the merge label;
68 // otherwise, keep the original label.
69 // 3) Go to the next edge. Collect all the points to be added along
70 // the edge; order them in the necessary direction and insert onto the
72 // 4) Grab the next point and return on step 2.
73 enrichedFacesPtr_ = new faceList(masterPatch_.size() + slavePatch_.size());
74 faceList& enrichedFaces = *enrichedFacesPtr_;
76 label nEnrichedFaces = 0;
78 const pointField& masterLocalPoints = masterPatch_.localPoints();
79 const faceList& masterLocalFaces = masterPatch_.localFaces();
80 const labelListList& masterFaceEdges = masterPatch_.faceEdges();
82 const faceList& slaveLocalFaces = slavePatch_.localFaces();
83 const labelListList& slaveFaceEdges = slavePatch_.faceEdges();
85 // For correct functioning of the enrichedPatch class, the slave
86 // faces need to be inserted first. See comments in
89 // Get reference to the point merge map
90 const Map<label>& pmm = pointMergeMap();
92 // Add slave faces into the enriched faces list
94 forAll (slavePatch_, faceI)
96 const face oldFace = slavePatch_[faceI];
97 const face oldLocalFace = slaveLocalFaces[faceI];
98 // Pout<< "old slave face " << faceI << ": " << oldFace
99 // << oldLocalFace.points(slavePatch_.localPoints()) << endl;
100 const labelList& curEdges = slaveFaceEdges[faceI];
102 DynamicList<label> newFace(oldFace.size()*enrichedFaceRatio_);
104 // Note: The number of points and edges in a face is always identical
105 // so both can be done is the same loop
109 Map<label>::const_iterator mpIter =
110 pmm.find(oldFace[i]);
112 if (mpIter == pmm.end())
115 newFace.append(oldFace[i]);
117 // Add the projected point into the patch support
118 if (!pointMap().found(oldFace[i]))
120 // Pout << "Inserting point from face " << i << " " << oldFace[i] << projectedSlavePoints[oldLocalFace[i]] << endl;
123 oldFace[i], // Global label of point
124 projectedSlavePoints[oldLocalFace[i]] // Projected posn
131 newFace.append(mpIter());
133 // Add the projected point into the patch support
134 if (!pointMap().found(mpIter()))
136 // Pout << "Inserting point " << mpIter() << " at " << projectedSlavePoints[oldLocalFace[i]] << endl;
139 mpIter(), // Merged global label of point
140 projectedSlavePoints[oldLocalFace[i]] // Projected posn
145 // Grab the edge points
147 const labelList& slavePointsOnEdge =
148 pointsIntoSlaveEdges[curEdges[i]];
149 // Pout << "slavePointsOnEdge for " << curEdges[i] << ": " << slavePointsOnEdge << endl;
150 // If there are no points on the edge, skip everything
151 // If there is only one point, no need for sorting
152 if (slavePointsOnEdge.size() > 0)
154 // Sort edge points in order
155 scalarField edgePointWeights(slavePointsOnEdge.size());
156 const point& startPoint = projectedSlavePoints[oldLocalFace[i]];
159 projectedSlavePoints[oldLocalFace.nextLabel(i)]
162 scalar magSqrE = magSqr(e);
172 "void enrichedPatch::calcEnrichedFaces\n"
174 " const labelListList& pointsIntoMasterEdges,\n"
175 " const labelListList& pointsIntoSlaveEdges,\n"
176 " const pointField& projectedSlavePoints\n"
178 ) << "Zero length edge in slave patch for face " << i
179 << ". This is not allowed."
180 << abort(FatalError);
183 pointField slavePosOnEdge(slavePointsOnEdge.size());
185 forAll (slavePointsOnEdge, edgePointI)
187 slavePosOnEdge[edgePointI] =
188 pointMap().find(slavePointsOnEdge[edgePointI])();
190 edgePointWeights[edgePointI] =
191 (e & (slavePosOnEdge[edgePointI] - startPoint));
196 // Check weights: all new points should be on the edge
197 if (min(edgePointWeights) < 0 || max(edgePointWeights) > 1)
201 "void enrichedPatch::calcEnrichedFaces\n"
203 " const labelListList& pointsIntoMasterEdges,\n"
204 " const labelListList& pointsIntoSlaveEdges,\n"
205 " const pointField& projectedSlavePoints\n"
207 ) << "Invalid point edge weights. Some of points are"
208 << " not on the edge for edge " << curEdges[i]
209 << " of face " << faceI << " in slave patch." << nl
210 << "Min weight: " << min(edgePointWeights)
211 << " Max weight: " << max(edgePointWeights)
212 << abort(FatalError);
216 // Go through the points and collect them based on
217 // weights from lower to higher. This gives the
218 // correct order of points along the edge.
219 for (label passI = 0; passI < edgePointWeights.size(); passI++)
221 // Max weight can only be one, so the sorting is
222 // done by elimination.
223 label nextPoint = -1;
226 forAll (edgePointWeights, wI)
228 if (edgePointWeights[wI] < dist)
230 dist = edgePointWeights[wI];
235 // Insert the next point and reset its weight to exclude it
237 newFace.append(slavePointsOnEdge[nextPoint]);
238 edgePointWeights[nextPoint] = GREAT;
240 // Add the point into patch support if not already there
241 if (!pointMap().found(slavePointsOnEdge[nextPoint]))
243 // Pout << "Inserting point, pass 1: " << slavePointsOnEdge[nextPoint] << " " << slavePosOnEdge[nextPoint] << endl;
246 slavePointsOnEdge[nextPoint],
247 slavePosOnEdge[nextPoint]
253 // Pout<< "New slave face " << faceI << ": " << newFace << endl;
255 // Add the new face to the list
256 enrichedFaces[nEnrichedFaces].transfer(newFace.shrink());
260 // Add master faces into the enriched faces list
262 forAll (masterPatch_, faceI)
264 const face& oldFace = masterPatch_[faceI];
265 const face& oldLocalFace = masterLocalFaces[faceI];
266 // Pout << "old master face: " << oldFace << endl;
267 const labelList& curEdges = masterFaceEdges[faceI];
269 DynamicList<label> newFace(oldFace.size()*enrichedFaceRatio_);
271 // Note: The number of points and edges in a face is always identical
272 // so both can be done is the same loop
276 Map<label>::const_iterator mpIter =
277 pmm.find(oldFace[i]);
279 if (mpIter == pmm.end())
282 newFace.append(oldFace[i]);
284 // Add the point into patch support
285 if (!pointMap().found(oldFace[i]))
287 // Pout << "Inserting master point: " << oldFace[i] << " " <<
288 // masterLocalPoints[oldLocalFace[i]] << endl;
292 masterLocalPoints[oldLocalFace[i]]
299 newFace.append(mpIter());
301 // Add the point into support
302 if (!pointMap().found(mpIter()))
304 // Pout << "Inserting master 2 " << mpIter() << " " << masterLocalPoints[oldLocalFace[i]] << endl;
308 masterLocalPoints[oldLocalFace[i]]
313 // Grab the edge points
315 const labelList& masterPointsOnEdge =
316 pointsIntoMasterEdges[curEdges[i]];
318 // If there are no points on the edge, skip everything
319 // If there is only one point, no need for sorting
320 if (masterPointsOnEdge.size() > 0)
322 // Sort edge points in order
323 scalarField edgePointWeights(masterPointsOnEdge.size());
324 const point& startPoint = masterLocalPoints[oldLocalFace[i]];
327 masterLocalPoints[oldLocalFace.nextLabel(i)]
330 scalar magSqrE = magSqr(e);
340 "void enrichedPatch::calcEnrichedFaces\n"
342 " const labelListList& pointsIntoMasterEdges,\n"
343 " const labelListList& pointsIntoSlaveEdges,\n"
344 " const pointField& projectedSlavePoints\n"
346 ) << "Zero length edge in master patch for face " << i
347 << ". This is not allowed."
348 << abort(FatalError);
351 pointField masterPosOnEdge(masterPointsOnEdge.size());
353 forAll (masterPointsOnEdge, edgePointI)
355 masterPosOnEdge[edgePointI] =
356 pointMap().find(masterPointsOnEdge[edgePointI])();
358 edgePointWeights[edgePointI] =
359 (e & (masterPosOnEdge[edgePointI] - startPoint));
364 // Check weights: all new points should be on the edge
365 if (min(edgePointWeights) < 0 || max(edgePointWeights) > 1)
369 "void enrichedPatch::calcEnrichedFaces\n"
371 " const labelListList& pointsIntoMasterEdges,\n"
372 " const labelListList& pointsIntoSlaveEdges,\n"
373 " const pointField& projectedSlavePoints\n"
375 ) << "Invalid point edge weights. Some of points are"
376 << " not on the edge for edge " << curEdges[i]
377 << " of face " << faceI << " in master patch." << nl
378 << "Min weight: " << min(edgePointWeights)
379 << " Max weight: " << max(edgePointWeights)
380 << abort(FatalError);
384 // Go through the points and collect them based on
385 // weights from lower to higher. This gives the
386 // correct order of points along the edge.
387 for (label pass = 0; pass < edgePointWeights.size(); pass++)
389 // Max weight can only be one, so the sorting is
390 // done by elimination.
391 label nextPoint = -1;
394 forAll (edgePointWeights, wI)
396 if (edgePointWeights[wI] < dist)
398 dist = edgePointWeights[wI];
403 // Insert the next point and reset its weight to exclude it
405 newFace.append(masterPointsOnEdge[nextPoint]);
406 edgePointWeights[nextPoint] = GREAT;
408 // Add the point into patch support
409 if (!pointMap().found(masterPointsOnEdge[nextPoint]))
413 masterPointsOnEdge[nextPoint],
414 masterPosOnEdge[nextPoint]
420 // Pout << "New master face: " << newFace << endl;
422 // Add the new face to the list
423 enrichedFaces[nEnrichedFaces].transfer(newFace.shrink());
427 // Check the support for the enriched patch
432 Info<< "Enriched patch support OK. Slave faces: "
433 << slavePatch_.size() << " Master faces: "
434 << masterPatch_.size() << endl;
440 "void enrichedPatch::calcEnrichedFaces\n"
442 " const labelListList& pointsIntoMasterEdges,\n"
443 " const labelListList& pointsIntoSlaveEdges,\n"
444 " const pointField& projectedSlavePoints\n"
446 ) << "Error in enriched patch support"
447 << abort(FatalError);
453 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
455 const Foam::faceList& Foam::enrichedPatch::enrichedFaces() const
457 if (!enrichedFacesPtr_)
459 FatalErrorIn("const faceList& enrichedPatch::enrichedFaces() const")
460 << "Enriched faces not available yet. Please use "
461 << "void enrichedPatch::calcEnrichedFaces\n"
463 << " const labelListList& pointsIntoMasterEdges,\n"
464 << " const labelListList& pointsIntoSlaveEdges,\n"
465 << " const pointField& projectedSlavePoints\n"
467 << " before trying to access faces."
468 << abort(FatalError);
471 return *enrichedFacesPtr_;
475 // ************************************************************************* //